Sunday, February 21, 2010

How to disable Bonjour on OSX 10.6 (Snow Leopard)

Bonjour is Apple's zeroconf protocol and iTunes (among others) uses it to broadcast the existence of its shared library, which I find annoying because it's quite chatty on the network. In the past shutting down mDNSResponder was enough to keep it quiet but this doesn't work as intended anymore on Snow Leopard as all DNS activity goes through mDNSResponder now.

Apple's KB explains how to properly disable those broadcast advertisements:
  1. sudo vim /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist
  2. Add <string>-NoMulticastAdvertisements</string> at the end of the ProgramArguments array.
  3. Save the file
  4. Restart mDNSResponder:
    sudo launchctl unload /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist
    sudo launchctl load /System/Library/LaunchDaemons/com.apple.mDNSResponder.plist
There's no need to reboot unlike what the KB says, as you long as you restart mDNSResponder.

Friday, February 5, 2010

Linux pipe count

I recently needed to keep track of the number of pipes opened by a server and I was using lsof -nw | fgrep FIFO but this was rather slow.

Here's a better way of counting the number of pipes opened:
# find /proc/[0-9]*/fd -lname 'pipe:*' 2>/dev/null -printf "%l\n" | wc -l
1294
# find /proc/[0-9]*/fd -lname 'pipe:*' 2>/dev/null -printf "%l\n" | sort -u | wc -l
16
So in this case there are 16 different pipes opened on this system and 1294 FDs associated with one or the other end of each pipe. Let's see how many FDs are associated with each pipe:
# find /proc/[0-9]*/fd -lname 'pipe:*' 2>/dev/null -printf "%l\n" | sort | uniq -c
1 pipe:[10420]
4 pipe:[1752247694]
4 pipe:[1752247702]
2 pipe:[1752247883]
2 pipe:[234248737]
1 pipe:[2597396375]
504 pipe:[4194986548]
255 pipe:[4194986549]
252 pipe:[4194986551]
252 pipe:[4194986552]
2 pipe:[4213391983]
1 pipe:[4214019609]
2 pipe:[480771901]
8 pipe:[480771902]
2 pipe:[6087]
2 pipe:[6288]
So certain pipes are much more popular than others.

Bonus script to find out which pipe is used by which process:
# find /proc/[0-9]*/fd -lname 'pipe:*' -printf "%p/%l\n" 2>/dev/null | python -c 'import os
import sys
pid2cmd = {}
def cmdname(pid):
cmd = os.path.basename(os.readlink("/proc/%s/exe" % pid))
pid2cmd[pid] = cmd
return cmd
pipes = {}
for line in sys.stdin:
line = line.rstrip().split("/")
pid, pipe = line[2], line[5]
cmd = pid2cmd.get(pid) or cmdname(pid)
pipes.setdefault(pipe, {}).setdefault(cmd, 0)
pipes[pipe][cmd] += 1
n = 0
for pipe, cmds in sorted(pipes.iteritems()):
print pipe,
for cmd, cnt in cmds.iteritems():
n += int(cnt)
print "%s=%s" % (cmd, cnt),
print
print len(pipes), "pipes using", n, "fds"'
pipe:[10420] rpc.statd=1
pipe:[1752247694] dsm_sa_datamgr32d.5.8.0.4961=4
pipe:[1752247702] dsm_sa_datamgr32d.5.8.0.4961=4
pipe:[1752247883] dsm_sa_datamgr32d.5.8.0.4961=2
pipe:[234248737] famd=2
pipe:[2597396375] ntpd=1
pipe:[4194986548] apache2=504
pipe:[4194986549] dash=1 rotatelogs=1 apache2=253
pipe:[4194986551] apache2=252
pipe:[4194986552] apache2=252
pipe:[4214440803] sshd=2
pipe:[4214877266] find=1
pipe:[480771901] master=2
pipe:[480771902] qmgr=2 pickup=2 master=2 tlsmgr=2
pipe:[6087] init=2
pipe:[6288] udevd=2
16 pipes using 1294 fds
So apache2 is the heavy pipe user here. Yay for mpm_prefork</irony>