Overview
What will you do, if you are running a mission critical DHCP server and you want to adjust some traffic policies of dhcpmod kernel module without process restart?
What will you do, if you are running a mission critical DHCP server and you want to adjust some traffic policies of dhcpmod kernel module without process restart?
The
answer is: by using Solaris MDB.
Finding out where the traffic policies reside
Finding out where the traffic policies reside
It
is assumed that you have already heard about Solaris STREAMS or even
more have read STREAMS Programming Guide.
The
basic concept is that Solaris exports special DDI interfaces for
working with queues (queue_t). We use reading queue parameter
q_ptr which stores the address to user-specific pointer - a
structure created by routine mstrmod_open() when the queue is
opened. In the case of dhcpmod
all traffic policy parameters resides as unsigned integers in that
structure. You can consult the dhcpmod's sources for more details.
Firstly
you should look for dhcpmod
in system streams cache:
mdb
-k
>
::walk stream_head_cache | ::stream
<output
stripped>
|
^
v
|
+-----------------------+-----------------------+
|
0xffffffff9f2ce648| 0xffffffff9f2ce550|
|
dhcpmod | dhcpmod |
|
| |
|
cnt = 0t0 | cnt = 0t0 |
|
flg = 0x00000822 | flg = 0x00000832|
+-----------------------+-----------------------+
|
^
<output
stripped>
0xffffffff9f2ce550
is a pointer to reading queue of filtering instance 1.
We
need to print more information about it:
>
ffffffff9f2ce550::print queue_t
{
q_qinfo
= mstrmod_rinit
q_first
= 0
q_last
= 0
q_next
= 0xffffffffa1546008
q_link
= 0
q_ptr
= 0xfffffe86a09d7400
q_count
= 0
q_flag
= 0x832
q_minpsz
= 0
q_maxpsz
= 0xffffffffffffffff
q_hiwat
= 0
q_lowat
= 0
q_bandp
= 0
q_lock
= {
_opaque
= [ 0 ]
}
q_stream
= 0xffffffffa1558d90
q_syncq
= 0xffffffff9f2ce740
q_nband
= 0
q_wait
= {
_opaque
= 0
}
q_sync
= {
_opaque
= 0
}
q_nfsrv
= 0xfffffe86f89d0aa8
q_nbsrv
= 0
q_draining
= 0
q_struiot
= 0xffff
q_syncqmsgs
= 0
q_mblkcnt
= 0
q_sqhead
= 0
q_sqtail
= 0xffffffff91e1c600
q_sqflags
= 0
q_rwcnt
= 0
q_sqnext
= 0
q_sqprev
= 0
q_sqtstamp
= 0x3a55c18
q_qtstamp
= 0xbaddcafebaddcafe
q_spri
= 0
q_fp
= 0xfffffe8683fca0b0
}
The
parameter q_flag
is from struct
module_info
and is equal 0x832 (for module dhcpmod).
About STREAMS structures you can consult
<sys/stream.h>
for more details
.
The
parameter q_qinfo = mstrmod_rinit is our reading queue's
primitive which confirms we are in the right place. The parameter
q_ptr (0xfffffe86a09d7400) is our structure.
Now
we dump what first 4 paragraphs (in MDB terms) of structure contains:
>
0xfffffe86a09d7400::dump -eq -w 4
fffffe86a09d7400:
9e9e82b0
ffffffff 00000000 00000000
8f81835
00000001 00000001 00000001
0000000a
00000005 00000001 00000000
000000ff
00000000 48a36f90 fffffe82
Offset
18 is the runtime-dependent instance ID of our queue (you can verify
it's value via kstat as discussed earlier). If it isn't what
you've requested, you should iterate via ::walk
stream_head_cache to the next instance
until succeeded.
>
0xffffffe86a09d7400+18/B
0xffffffe86a09d7400:
1
Offset
20 contains allowed packets per minute parameter. Offset 30 shows
discard by rate policy parameter.
Note
that for 32-bit kernel offset values will be different. Specifically,
instance ID offset will be 9, allowed packets per minute offset will
be 10, discard by rate policy offset will be 15.
Now
we can accomplish our tasks.
Task
1. Turn off discard by rate policy.
Verifying
discard by rate policy's current setting:
>
0xffffffe86a09d7400+30/B
0xffffffe86a09d7400:
ff
You
see ff → 255
Writing
a new value:
>
0xffffffe86a09d7400+30/W 0x0
0xffffffe86a09d7400:
0xff = 0x0
Task
2. Increasing allowed packets per minute value
Verifying
allowed packets per minute value:
>
0xffffffe86a09d7400+20/B
0xffffffe86a09d7400:
a
You
see a → 10
To
increase allowed packets per minute value from 10 to 20 (0x14), type:
>
0xffffffe86a09d7400+20/W 0x14
0xffffffe86a09d7400:
0xa = 0x14