Tuesday Oct 27, 2009

I've been experimenting with Mercurial Queues with the idea of sharing their mysteries with OpenSolaris developers so we can all integrate multiple changesets and keep one fix per changeset.

Essentially mq allows you to take a snapshot of your changes and create a patch file. You may then make additional changes to be applied to the same patch file (qrefresh) or create a new patch (qnew) These patches may then be removed (qpop) and reapplied (qpush) at your leisure. So that's the theory, lets take a look using an example:

Enabling mq

To enable mq on OpenSolaris simply add it to your extensions in .hgrc:

$ head -2 ~/.hgrc
[extensions]
mq=

Some data to work on.

For the following examples I've created a repository and added to it a simple C 'First program' and a make(1) file to compile and delete the program... Complete with some faults to fix.

$ hg init qexample
$ cd qexample
$ echo 'int\nmain(int argc, char *argv[])\n{\n\tprintf("hello word");\n}'
$ 1> hi.c
$ echo src='hi.c\nbin=${src:%.c=%}\nall: ${bin}\nclobber:\n\trm ${bin}'
$ 1> Makefile
$ hg commit -m 'First program' -u beginner -A hi.c Makefile
$ cd ..

Clone repository and initialise for use with mq

Create a clone of qexample called qex1 and initialise it for mq using qinit -c.

$ hg clone qexample qex1
updating working directory
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ cd qex1
$ hg qinit -c

Fix Makefile clobber target

The Makefile has some issues, firstly the clobber target.

$ make clobber hi
rm hi
rm: hi: No such file or directory
*** Error code 2
make: Fatal error: Command failed for target `clobber'

First Patch, Makefile

So here is our first issue, the clobber build fails as 'rm' failed and causes make to exit. To address that we can simply add a -f to rm, so lets do that for our first patch.

$ hg qnew Makefile

The qnew command states we want to create a new patch, the argument is the name of the patch. This action also creates a changeset, don't be concerned about that now.

$ hg log
changeset:   1:d8ddc677fa77
tag:         qtip
tag:         Makefile
tag:         tip
tag:         qbase
user:        Stacey Marshall ‹Stacey.Marshall-AT-Sun-DOT-COM›
date:        Tue Oct 27 21:17:03 2009 +0000
summary:     [mq]: Makefile

changeset:   0:390c5f52f8e3
tag:         qparent
user:        beginner
date:        Tue Oct 27 21:17:02 2009 +0000
summary:     First program

$ sed 's/rm /rm -f /' Makefile > m
$ mv m Makefile
$ make clobber hi
rm -f hi
cc    -o hi hi.c 
"hi.c", line 4: warning: implicit function declaration: printf
$ hg qrefresh

After applying the fix clobber target now works. However, now the compiler's giving us warnings! That's a new issue, so I update the Makefile change using qrefresh and start a new patch:

Second patch, remove warnings.

This time qnew is used with the -m option to add a description. Note this description is also applied to the changeset, it can be changed later if necessary:

$ hg qnew -m 'remove implicit function delcaration warnings' fix1
$ (echo '#include ‹stdio.h›'; cat hi.c) > new.c
$ mv new.c hi.c
$ hg log -l1
changeset:   2:4ffb58a8196f
tag:         qtip
tag:         tip
tag:         fix1
user:        Stacey Marshall ‹Stacey.Marshall-AT-Sun-DOT-COM›
date:        Tue Oct 27 21:17:03 2009 +0000
summary:     remove implicit function declaration warnings

$
$ hg qdiff
diff -r d0b382d0a781 hi.c
--- a/hi.c	Tue Oct 27 21:17:03 2009 +0000
+++ b/hi.c	Tue Oct 27 21:17:03 2009 +0000
-AT--AT- -1,3 +1,4 -AT--AT-
+#include ‹stdio.h›
 int
 main(int argc, char *argv[])
 {
$ make hi
cc    -o hi hi.c 
$ hg qrefresh

The include was added to hi.c to remove the warning, and again the change updated using qrefresh.

Third patch, retrospective patching

Its likely that you'll start making changes before remembering to start a patch with qnew. For those occasions the -f option comes to hand to place all un-committed changes in to the patch. Verified below with qdiff:

$ ./hi
hello word$ # Doh! No new line, and it was meant to say 'world'!
$ sed 's/hello word/Hello world!\\n/' hi.c > new.c
$ mv new.c hi.c
$ hg qnew -f -m 'Fix world' message
$ hg qdiff
diff -r 8a838c77402f hi.c
--- a/hi.c	Tue Oct 27 21:17:03 2009 +0000
+++ b/hi.c	Tue Oct 27 21:17:04 2009 +0000
-AT--AT- -2,5 +2,5 -AT--AT-
 int
 main(int argc, char *argv[])
 {
-	printf("hello word");
+	printf("Hello world!\n");
 }

Listing patches with qseries

The qseries command shows us which patches have been applied, use the -v option to display 'A' (applied) and 'U' (un-applied) flags:

$ hg qseries -v
0 A Makefile
1 A fix1
2 A message
$ cat hi.c
#include ‹stdio.h›
int
main(int argc, char *argv[])
{
	printf("Hello world!\n");
}
$

Traversing the patches to make other changes.

Lets assume we want to make another change to the Makefile, but we want to keep just the one patch for changes to Makefile. To accomplish this we pop the other two patches off. In the following that's done by naming the patch to pop to:

$ hg qpop Makefile
now at: Makefile
$ hg qseries -v
0 A Makefile
1 U fix1
2 U message

Note now that the other two patches are un-applied.

With the just the original patch applied modify the Makefile, update the patch using qrefresh and then re-apply all the other patches using qpush -a.

$(echo '# Makefile example';cat Makefile)>new
$ mv new Makefile
$ hg qrefresh
$ hg qdiff
diff -r 390c5f52f8e3 Makefile
--- a/Makefile	Tue Oct 27 21:17:02 2009 +0000
+++ b/Makefile	Tue Oct 27 21:17:04 2009 +0000
-AT--AT- -1,5 +1,6 -AT--AT-
+# Makefile example
 src=hi.c
 bin=${src:%.c=%}
 all: ${bin}
 clobber:
-	rm ${bin}
+	rm -f ${bin}
$ hg qpush -a

Caution!

Some caution is needed when you want two patches that edit the same file. Its doable but because underneath patch(1) is being used you may need to manually merge in rejects.

Another gotcha on older versions of Mercurial is if you add a file in a patch-queue. If the patch is popped off you may need to re-add it (hg add). Lets see that in action by adding a new file which of course requires adding to the Makefile too... This seems to be fixed however in version 1.3.1:

$ hg qpush -a
applying fix1
applying message
now at: message
$ hg qnew bye
$ sed 's/Hello world/Bye/' hi.c > bye.c
$ hg add bye.c
$ : Make changes to makefile...
$ hg qrefresh
$ hg qpop Makefile
now at: Makefile
$ sed 's/hi.c/hi.c bye.c/' Makefile >new
$ head -2 new
# Makefile example
src=hi.c bye.c
$ mv new Makefile
$ hg qrefresh
$ hg qpush -a
applying fix1
applying message
applying bye
now at: bye
$ hg log bye.c || hg add bye.c # NEED TO CONFIRM!
$ hg log bye.c
changeset:   4:cdb5958dcd87
tag:         qtip
tag:         tip
tag:         bye
user:        Stacey Marshall ‹Stacey.Marshall-AT-Sun-DOT-COM›
date:        Tue Oct 27 21:17:05 2009 +0000
summary:     imported patch bye


$ make
cc    -o hi hi.c 
cc    -o bye bye.c 
$ 

Updating your repository - pull and update.

It is most likely someone is going to have integrated (push) between your original clone and push, and that you'd like to merge those changes.

So Firstly, for the example, add a changeset to our parent repo;

$ hg clone ../qexample tmp
$ cd tmp
$ echo "README...  TBD" > README
$ hg add README
$ hg commit -u beginner -m 'Added README for support.'
$ hg push
$ cd ..
$ hg incoming -v
comparing with /export/home/sm26363/Mercurial/Mercurial/qexample
searching for changes
changeset:   1:2048a9e0068b
tag:         tip
user:        beginner
date:        Tue Oct 27 21:17:05 2009 +0000
files:       README
description:
Added README for support.

$ 

Now Hold onto your seats, this is a bit of roller-coaster ride!

Firstly, we save the series of patches using qsave, with some essential options:

  • -c : Copy Patch directory
  • -n : Specify name of directory - By default it uses patches.N where N is next number in series until an non-existent directory is found within the root .hg directory.
  • -e : Empty the queue status file - The status file holds information about which patches are applied, so deleting it makes it look as though the patch queue is empty. The changesets are stripped of their special tags.

$ hg qsave -e -c -n incoming
copy /export/home/sm26363/Mercurial/Mercurial/qex1/.hg/patches to /export/home/sm26363/Mercurial/Mercurial/qex1/.hg/incoming
$ hg glog --template '{rev}:{node|short} {author|user}\n{desc|firstline}\n\n'
@  5:db6e2d5b6aa2 Stacey
|  hg patches saved state
|
o  4:cdb5958dcd87 Stacey
|  imported patch bye
|
o  3:d20726d3cc4d Stacey
|  Fix world
|
o  2:63144e5ebe68 Stacey
|  remove implicit function declaration warnings
|
o  1:be53b09aed16 Stacey
|  [mq]: Makefile
|
o  0:390c5f52f8e3 beginner
   First program

we're now ready to pull the incoming changes over, DON'T use the -u option. The update needs to be done separately:

$ hg pull
pulling from /export/home/sm26363/Mercurial/Mercurial/qexample
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)
$ hg glog --template "{rev}:{node|short} {author|user}\n{desc|firstline}\n\n"\
 -l3
o  6:2048a9e0068b beginner
|  Added README for support.
|
| @  5:db6e2d5b6aa2 Stacey
| |  hg patches saved state
| |
| o  4:cdb5958dcd87 Stacey
| |  imported patch bye
| |

The pull done, as normal we have multiple heads and possibly files that need merging. But as we're using patches we'll simply overwrite, local changes using option -C and re-apply the patches using qpush with the following arguments:

  • -m : Merge from another queue - This triggers a three-way merge if the patch fails to apply with the applicable changeset. The result is a new patch based on the changes.
  • -n : Name of other-queue - the backup from previous step.
  • -a : All patches.

$ hg update -C tip
3 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ hg qpush -m -n incoming -a
merging with queue at: /export/home/sm26363/Mercurial/Mercurial/qex1/.hg/incoming
applying Makefile
applying fix1
applying message
applying bye
now at: bye
$ 
$ hg glog --template "{rev}:{node|short} {author|user}\n{desc|firstline}\n\n" 
@    11:8db2598210ab Stacey
|\   imported patch bye
| |
| o    10:2d966b806fb1 Stacey
| |\   Fix world
| | |
| | o    9:e63a43ac5532 Stacey
| | |\   remove implicit function declaration warnings
| | | |
| | | o    8:a1205da4671a Stacey
| | | |\   imported patch Makefile
| | | | |
| | | | o  7:3f838495d0e4 Stacey
| | | | |  [mq]: merge marker
| | | | |
| | | | o  6:2048a9e0068b beginner
| | | | |  Added README for support.
| | | | |
+---------o  5:db6e2d5b6aa2 Stacey
| | | | |    hg patches saved state
| | | | |
o | | | |  4:cdb5958dcd87 Stacey
|/ / / /   imported patch bye
| | | |
o | | |  3:d20726d3cc4d Stacey
|/ / /   Fix world
| | |
o | |  2:63144e5ebe68 Stacey
|/ /   remove implicit function declaration warnings
| |
o |  1:be53b09aed16 Stacey
|/   [mq]: Makefile
|
o  0:390c5f52f8e3 beginner
   First program

As the fictional character Ford Prefect would say, “Don't Panic!”. That is what we were expecting. We're safe now to pop the patches off, stay with it:

$ hg qpop -a
patch queue now empty
$ hg glog --template "{rev}:{node|short} {author|user}\n{desc|firstline}\n\n"
@  6:2048a9e0068b beginner
|  Added README for support.
|
| o  5:db6e2d5b6aa2 Stacey
| |  hg patches saved state
| |
| o  4:cdb5958dcd87 Stacey
| |  imported patch bye
| |
| o  3:d20726d3cc4d Stacey
| |  Fix world
| |
| o  2:63144e5ebe68 Stacey
| |  remove implicit function declaration warnings
| |
| o  1:be53b09aed16 Stacey
|/   [mq]: Makefile
|
o  0:390c5f52f8e3 beginner
   First program

$ hg qpop -a -n incoming
using patch queue: /export/home/sm26363/Mercurial/Mercurial/qex1/.hg/incoming
saving bundle to /export/home/sm26363/Mercurial/Mercurial/qex1/.hg/strip-backup/be53b09aed16-temp
adding branch
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
patch queue now empty
$ hg qseries -v
0 U Makefile
1 U fix1
2 U message
3 U bye
$ hg qlog
@  changeset:   1:2048a9e0068b
|  tag:         tip
|  user:        beginner
|  date:        Tue Oct 27 21:17:05 2009 +0000
|  summary:     Added README for support.
|
o  changeset:   0:390c5f52f8e3
   user:        beginner
   date:        Tue Oct 27 21:17:02 2009 +0000
   summary:     First program

The above shows the incoming changeset and our patches un-applied. The patches may now be re-applied:


$ hg qpush -a
applying Makefile
applying fix1
applying message
applying bye
now at: bye
$ hg qlog
@  changeset:   5:a19f79097ba6
|  tag:         qtip
|  tag:         tip
|  tag:         bye
|  user:        Stacey Marshall ‹Stacey.Marshall@Sun-DOT-COM›
|  date:        Tue Oct 27 21:17:07 2009 +0000
|  summary:     imported patch bye
|
o  changeset:   4:74fc52a79383
|  tag:         message
|  user:        Stacey Marshall ‹Stacey.Marshall@Sun-DOT-COM›
|  date:        Tue Oct 27 21:17:07 2009 +0000
|  summary:     Fix world
|
o  changeset:   3:63ca0f087340
|  tag:         fix1
|  user:        Stacey Marshall ‹Stacey.Marshall@Sun-DOT-COM›
|  date:        Tue Oct 27 21:17:07 2009 +0000
|  summary:     remove implicit function declaration warnings
|
o  changeset:   2:c601487f5539
|  tag:         Makefile
|  tag:         qbase
|  user:        Stacey Marshall ‹Stacey.Marshall@Sun-DOT-COM›
|  date:        Tue Oct 27 21:17:07 2009 +0000
|  summary:     imported patch Makefile
|
o  changeset:   1:2048a9e0068b
|  tag:         qparent
|  user:        beginner
|  date:        Tue Oct 27 21:17:05 2009 +0000
|  summary:     Added README for support.
|
o  changeset:   0:390c5f52f8e3
   user:        beginner
   date:        Tue Oct 27 21:17:02 2009 +0000
   summary:     First program

Preparing to push

The final step is to remove the queues, as with those intact we're unable to push. To accomplish this use qfinish But before we clear the queues take a backup of them using qcommit and clone as its likely we'll have to pull again as we raise to push.

Note: Simply doing a qcommit is not sufficient because qfinish tidies up the patches, a peek into the working files shows this best - I've avoided showing these details previously:

$ hg qcommit -m "pre-finish"
$ ls .hg/patches
bye       fix1      Makefile  message   series    status
$ hg qfinish -a
patch Makefile finalized without changeset message
patch bye finalized without changeset message
$ ls .hg/patches
series  status
$ 

By cloning the patches before qfinish we can then recover them after stripping off our patched changesets, Lets look at another example.

$ hg qcommit -m 'Pre-finish'
$ hg clone .hg/patches .hg/patches-backup
updating working directory
6 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg qpush -a
all patches are currently applied
$ hg qfinish -a
patch Makefile finalized without changeset message
patch bye finalized without changeset message
$ 

Now lets assume there is something to pull, we'll have to remove our outgoing changes using strip:

$ hg outgoing
comparing with /export/home/sm26363/Mercurial/Mercurial/qexample
searching for changes
changeset:   2:c601487f5539
user:        Stacey Marshall ‹Stacey.Marshall@Sun-DOT-COM›
date:        Tue Oct 27 21:17:07 2009 +0000
summary:     imported patch Makefile

changeset:   3:63ca0f087340
user:        Stacey Marshall ‹Stacey.Marshall@Sun-DOT-COM›
date:        Tue Oct 27 21:17:07 2009 +0000
summary:     remove implicit function declaration warnings

changeset:   4:74fc52a79383
user:        Stacey Marshall ‹Stacey.Marshall@Sun-DOT-COM›
date:        Tue Oct 27 21:17:07 2009 +0000
summary:     Fix world

changeset:   5:a19f79097ba6
tag:         tip
user:        Stacey Marshall ‹Stacey.Marshall@Sun-DOT-COM›
date:        Tue Oct 27 21:17:07 2009 +0000
summary:     imported patch bye

$ hg strip 2
2 files updated, 0 files merged, 1 files removed, 0 files unresolved
saving bundle to /export/home/sm26363/Mercurial/Mercurial/qex1/.hg/strip-backup/59b69da7d392-backup
$ hg log
changeset:   1:2048a9e0068b
tag:         tip
user:        beginner
date:        Tue Oct 27 21:17:05 2009 +0000
summary:     Added README for support.

changeset:   0:390c5f52f8e3
user:        beginner
date:        Tue Oct 27 21:17:02 2009 +0000
summary:     First program

$ 

Recover the backups:

$ rm -rf .hg/patches 
$ hg clone .hg/patches-backup .hg/patches
updating working directory
6 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg qseries -v
0 U Makefile
1 U fix1
2 U message
3 U bye
$ 

So there we have it, we can then check the incoming, if it touches anything we've edited then we can go through the merge operation above and or pull, update re-apply patches, finish and patch.

Changing changeset message

As seen above qfinish nicely told us that some changesets were missing messages. These can be applied using qrefresh -m:

$ hg qseries -v
0 U Makefile
1 U fix1
2 U message
3 U bye
$ hg qpush Makefile
applying Makefile
now at: Makefile
$ hg qrefresh -m "Makefile changes"
$ hg qpush bye
applying fix1
applying message
applying bye
now at: bye
$ hg qrefresh -m "Bye: says goodbye"
$ hg glog
@  changeset:   5:202431aaf294
|  tag:         qtip
|  tag:         tip
|  tag:         bye
|  user:        Stacey Marshall ‹Stacey.Marshall@Sun-DOT-COM›
|  date:        Tue Oct 27 22:45:47 2009 +0000
|  summary:     Bye: says goodbye
|
o  changeset:   4:7494b600f084
|  tag:         message
|  user:        Stacey Marshall ‹Stacey.Marshall@Sun-DOT-COM›
|  date:        Tue Oct 27 22:45:21 2009 +0000
|  summary:     Fix world
|
o  changeset:   3:69c047974d13
|  tag:         fix1
|  user:        Stacey Marshall ‹Stacey.Marshall@Sun-DOT-COM›
|  date:        Tue Oct 27 22:45:21 2009 +0000
|  summary:     remove implicit function declaration warnings
|
o  changeset:   2:439652f08146
|  tag:         Makefile
|  tag:         qbase
|  user:        Stacey Marshall ‹Stacey.Marshall@Sun-DOT-COM›
|  date:        Tue Oct 27 22:45:15 2009 +0000
|  summary:     Makefile changes
|
o  changeset:   1:2048a9e0068b
|  tag:         qparent
|  user:        beginner
|  date:        Tue Oct 27 21:17:05 2009 +0000
|  summary:     Added README for support.
|
o  changeset:   0:390c5f52f8e3
   user:        beginner
   date:        Tue Oct 27 21:17:02 2009 +0000
   summary:     First program

Note: Obviously for OpenSolaris repository the messages must follow the bug-id synopsis format.

References

  1. Mq Tutorial
  2. Merging Patches
  3. Multiple changeset pushes to ON - utilising ZFS snapshots for rollback

Last but not least, hg help mq.

Stace

Wednesday Sep 30, 2009

When I was interviewed for my first position as a network support engineer (front line) for Sun Services I was asked "What tools would you use to diagnose DNS issues?" To which of course I answered "dig, the Domain Information Groper". The guy looked at me blankly (I know his name) and said "No... what else? to LOOKUP"? To me there really wasn't anything else, or did he mean host(1)... I can honestly say I'd never heard of nslookup(1) but then he'd never heard of dig. But I knew I was right in my answer. I was astonished to find that Solaris didn't provide dig(1) out-of-the box then. I am happy to report that its available on all supported releases today.

What brought this memory to mind is the feeling that I got in my stomach then occurred again when I read the statement; "Once installed, T-patches do not show their "T" prefix in the output of showrev -p ... They never did". I'm certain circa 1998 'showrev -p' did just that. I even managed to find a single link which backed me up, http://ftp.lanet.lv/ftp/sun-info/sun-patches/106699.readme, also available from SunSolve. So what's the consensus here? Am I right or am I right?

Thursday Aug 27, 2009

BIND 9's named(1M) performance can be vastly improved when running on Solaris operating environment where either no IPv4 or no IPv6 connectivity is available.

The issue is documented in the named(1M) manual page:

BUGS
     By default, named attempts to contact remote name servers by
     either their IPv4 or IPv6 address, even though the host sys-
     tem does not have either IPv4 or IPv6 connectivity (that is,
     a  configured  and active interface). To address this issue,
     either provide the missing connectivity or use the  relevant
     -4  or  -6  command  line option. When using svccfg(1M), set
     application property options/ip_interfaces to either IPv4 or
     IPv6.

Essentially 'named' receives both IPv4 and IPv6 addresses for name servers. As it goes about its business of resolving queries it attempts to send UDP packets to those addresses. Ideally it would be informed of a missing transport and quickly fail. Alas defect 6320428 "sendto() should return errors up the stack" means that does not happen and thus 'named' waits for a response that is never going to come.

As an example, lets take a peek at the root name server addresses using dig (domain Internet Groper):

$ dig . ns

; <<>> DiG 9.3.6-P1 <<>> . ns
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 878
;; flags: qr rd ra; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 14

;; QUESTION SECTION:
;.				IN	NS

;; ANSWER SECTION:
.			498528	IN	NS	c.root-servers.net.
.			498528	IN	NS	d.root-servers.net.
.			498528	IN	NS	e.root-servers.net.
.			498528	IN	NS	f.root-servers.net.
.			498528	IN	NS	g.root-servers.net.
.			498528	IN	NS	h.root-servers.net.
.			498528	IN	NS	i.root-servers.net.
.			498528	IN	NS	j.root-servers.net.
.			498528	IN	NS	k.root-servers.net.
.			498528	IN	NS	l.root-servers.net.
.			498528	IN	NS	m.root-servers.net.
.			498528	IN	NS	a.root-servers.net.
.			498528	IN	NS	b.root-servers.net.

;; ADDITIONAL SECTION:
a.root-servers.net.	498238	IN	A	198.41.0.4
a.root-servers.net.	195801	IN	AAAA	2001:503:ba3e::2:30
b.root-servers.net.	593090	IN	A	192.228.79.201
c.root-servers.net.	412662	IN	A	192.33.4.12
d.root-servers.net.	592857	IN	A	128.8.10.90
e.root-servers.net.	419480	IN	A	192.203.230.10
g.root-servers.net.	26029	IN	A	192.112.36.4
i.root-servers.net.	592963	IN	A	192.36.148.17
j.root-servers.net.	498528	IN	A	192.58.128.30
j.root-servers.net.	498528	IN	AAAA	2001:503:c27::2:30
k.root-servers.net.	593006	IN	A	193.0.14.129
k.root-servers.net.	589950	IN	AAAA	2001:7fd::1
l.root-servers.net.	3378	IN	A	199.7.83.42
l.root-servers.net.	195801	IN	AAAA	2001:500:3::42

;; Query time: 3 msec
;; SERVER: 129.156.86.11#53(129.156.86.11)
;; WHEN: Thu Aug 27 12:53:49 2009
;; MSG SIZE  rcvd: 500

As documented in named(1M) the solution is to enable only IPv4 or IPv6 transports. On Solaris 10 or above this should be accomplished using SMF properties:

      Example 1 Configuring named to Transmit Only over IPv4  Net-
     works


     The following command sequence configures named such that it
     will transmit only over IPv4 networks.


       # svccfg -s svc:network/dns/server:default setprop \
       > options/ip_interfaces=IPv4
       # svcadm refresh svc:network/dns/server:default
       #

On Solaris 8 or 9 modify init.d(4) script /etc/init.d/inetsvc and append either -4 or -6 to the BIND 9 startup line.

Note BIND 9 should be used as documented in SunAlert 239392.

For example, the following is a excerpt from a modified /etc/init.d/inetsvc to start named(1M) so that it only uses IPv4 transports:

if [ -f /usr/lib/dns/named -a -f /etc/named.conf ]; then
        echo 'starting internet domain name server.'
        /usr/lib/dns/named -4&
fi

By limiting 'named' to the available transport its performance is vastly improved.

Wednesday Aug 26, 2009

BIND 9.3.6-P1 requires poll(7d) to improve networking performance which was very badly impacted by the changes applied to BIND to help fight of attack from the Kaminsky issue, Sun Alert 239392.

If BIND's named process is running within a chroot(2) environment then that environment requires the poll device to be installed. Though I recommend using zones(5) and Role-Based Access Control, rbac(5), rather than chroot environments which does then avoid this issue.

Example 1: missing poll device:

# /usr/sbin/named -t /var/named -u dns -f -g
31-Jan-2009 21:07:16.697 starting BIND 9.3.6 -t /var/named -u dns -f -g
31-Jan-2009 21:07:16.697 found 8 CPUs, using 8 worker threads
31-Jan-2009 21:07:16.715 socket.c:3259: unexpected error:
31-Jan-2009 21:07:16.715 open(/dev/poll) failed: No such file or directory
31-Jan-2009 21:07:16.715 ./main.c:495: unexpected error:
31-Jan-2009 21:07:16.715 isc_socketmgr_create() failed: file not found
31-Jan-2009 21:07:16.715 create_managers() failed: unexpected error
31-Jan-2009 21:07:16.715 exiting (due to early fatal error)

The '-t /var/named' option causes named to use the /var/named as the chroot directory. Named is unable to continue because the required device /dev/poll is missing.

To address the missing poll device simply create it:

Example 2: Create poll device with same properties as root (/) device using mknod(1M)

   # ls -ld /devices/pseudo/poll@0:poll
   crw-rw-rw-  1 root  sys  138, 0 May 28 04:25 /devices/pseudo/poll@0:poll
   # cd /var/named/dev
   # ls
   null    random
   # mknod poll c 138 0
   # chmod 666 poll

If using SMF remember to clear and re-enable the service:

   # svcadm clear svc:/network/dns/server:default
   # svcadm enable svc:/network/dns/server:default

See also CR 6799867

Thursday Apr 30, 2009

Has it really been five years since the creation of blogs.sun.com? And six years since the integration of Dtrace? Clearly I'm having fun as the time seems to have flown by.

I'm currently eager to get on and use my cloud space. Like others I'm too thinking of using it for backups of important information that I'd really rather not lose. But I'm also looking forward to using it as a repository for some data that I currently hold on my Treo and that I access mostly on the Desktop by transferring the memory card; which I hope I don't lose. I'm waiting with bated breath for the Palm Pre to be made available in the UK for the same reason. No dates mentioned as yet :-(

Friday Feb 20, 2009

The ISC (Internet Systems Consortium) have scheduled further training course on BIND. The next one is in March at the ISC's headquarters in Redwood City, CA. I'm looking forward to attending, last I heard there was still a couple of places open if your interested.

Monday Dec 15, 2008

In my day-to-day role as a software engineer I share with my peers unified-differences derived from the diff(1) command. For example:


$ diff -u old new
  --- old	Wed Oct 29 14:36:47 2008
+++ new	Wed Oct 29 14:36:56 2008
@@ -1,9 +1,15 @@
 I
 really
-should
+ought
 provide
 better
 examples.
 
-Or at least use some of my daughters poetry
+Mary
+had
+a
+little 
+lamb,
+
+Or perhaps use some of my daughters poetry.

$

Where differences occur a line listing the original line number followed by the new line numbers are displayed which is followed by the changes. Lines removed from "new" are marked with a "-" at the beginning while lines added to "new" are marked with a "+". In the example its quite easy to see that line three has been removed and replaced. However it is sometimes not so obvious, the line numbers get a little confusing in ensuing conversation.

So I put together a little nawk script to display the line numbers in-line as well:

$ diff -u old new | udiffn
--- old	Wed Oct 29 14:36:47 2008
+++ new	Wed Oct 29 14:36:56 2008
 Old  New @@ -1,9 +1,15 @@
   1    1  I
   2    2  really
   3      -should
        3 +ought
   4    4  provide
   5    5  better
   6    6  examples.
   7    7  
   8      -Or at least use some of my daughters poetry
        8 +Mary
        9 +had
       10 +a
       11 +little 
       12 +lamb,
       13 +
       14 +Or perhaps use some of my daughters poetry.
   9   15  

Ideally diff(1) would have an option to provide this output but in the mean time this little tool will suffice:

$ cat ~/tools/sh/udiffn
#!/bin/nawk -f
# Add line numbers to unified diff output: diff -u old new | udiffn
/^No differences encountered/ ||		# No exit as intended as a pipe
/^$/ ||						# Blank lines
/^(\-\-\-|\+\+\+)/ {print; next;}		# diff Headers
/^@@ [-+][0-9]*,[0-9]* [+-][0-9]*,[0-9]* @@/ {	# Start of difference block
  i=split(substr($2,2), o, ",");		# old start line in o[1]
  j=split(substr($3,2), n, ",");		# new start line in n[1]
  l=length(n[1])+1;				# Numeric field length
  if (l <= 4 ) l = 4;
  printf("%*s %*s %s\n", l, "Old", l, "New", $0);
  next;
}

/^ /	{printf("%*s %*d %s\n", l, o[1]++, l, n[1]++, $0); next;}
/^\+/	{printf("%*s %*d %s\n", l, " ", l, n[1]++, $0); next;}
/^\-/	{printf("%*d %*s %s\n", l, o[1]++, l, " ", $0); next;}

/^Index: / {print; next}			# patch/wx header
/^diff -r/ {print; next}			# Mercurial header
# Everything else is unexpected.
{print "Er!",NR,$0;}

Friday Nov 14, 2008

I've just found out that it is possible to select Point-to-focus, my preferred focus policy, on Windows XP. I found the option in Tweak UI which can be down loaded from the MS Power Toys for Windows XP page. To enable Point-to-Focus run Tweak UI, navigate down the right pane to Mouse -> X-Mouse and select "Activation follows mouse (X-Mouse)". As of yet I have not found an option to stop raising the window on click!

I came across Tweak UI utility as having purchased a new 1TB disc I wanted to move the common "Shared" folders to it. I tried dragging the folder as suggested but this didn't seem to have the desired effect. Some goolge time later I found Tweak UI which also has an option to change those settings. Looks like there are some other useful tools in there too, such as CmdHere and DeskMan.

Thursday Nov 13, 2008

Music Man Poster

BATS latest production of The Music Man is now underway at the Haymarket Theatre in Basingstoke and running through to Saturday 22nd.

Both of my girls, Emily and Alice, are in the show performing together on alternating nights. I'm looking forward to seeing it on Friday as I've heard that this is another excellent performance by BATS.

The show features the signature song ‘Seventy-Six Trombones’. The story sees 'Professor' Harold Hill, a con man, whose scam is to convince parents he can teach their musically disinclined children to play instruments. He takes pre-orders for musical instruments and promises to form a band, when he promptly skips town and moves onto the next before he is found out. Harold arrives at River City, Iowa, where he meets their townspeople and therein the fun starts.

Friday Nov 07, 2008

A minor update to ut-where to add a '-V' option which causes ut-where to provide some additional verbosity in a zenity window. I can't see one wanting to use the option ongoing but its nice at first to help understand whats happening, for example when your screen does not automatically change because the utsettings are not set as you might expect them to be. Or because XRandR is not supported.

Wednesday Nov 05, 2008

My Sun Ray TM session can now automatically switch desktop size when moving between different clients.

For example:

Having logged on originally at my desk, Sun Ray 2FS with a 1920x1200 monitor

I pull my card and move to a break area with a Sun Ray 150 with a much smaller screen

The whole desktop is displayed, no panning required :-D

Sun Ray Server Software 4.1 includes a new standalone Xserver, Xnewt, based on Xorg 7.2 community source. Xnewt introduces the XRandR extension to Sun Ray which amongst other features enables the session to switch Video Resolution and resize the desktop dynamically. No more panning around when using on a smaller display, or unused space when moving to a larger display.

Using the example above, moving from the Sun Ray 2FS with a 1920x1200 monitor to a Sun Ray 150 xrandr reports:

$ /usr/X11/bin/xrandr -q
 SZ:    Pixels          Physical       Refresh
 0    640 x 480    ( 180mm x 135mm )
 1    800 x 600    ( 225mm x 169mm )
 2   1024 x 768    ( 289mm x 216mm )
 3   1152 x 900    ( 325mm x 254mm )
 4   1280 x 1024   ( 361mm x 289mm )
 5   1400 x 1050   ( 395mm x 296mm )
 6   1440 x 900    ( 406mm x 254mm )
 7   1600 x 1024   ( 451mm x 289mm )
 8   1600 x 1200   ( 451mm x 339mm )
 9   1680 x 1050   ( 474mm x 296mm )
 10  1920 x 1080   ( 542mm x 305mm )
*11  1920 x 1200   ( 542mm x 339mm )
Current rotation - normal
Current reflection - none
Rotations possible - normal 
Reflections possible - none

While by comparison the Sun Ray setting, as reported by utset is somewhat smaller:

$ /opt/SUNWut/bin/utset | grep '^Display Timing 1:'
Display Timing 1: 1024x768@60
$

Therefore I can dynamically change the desktop using xrandr command and shrink my desktop accordingly:

$ /usr/X11/bin/xrandr -s 1024x768

The one caveat at this time is that for xrandr to grow the desktop Xorg must have allocated sufficient memory for it. Obviously with the example above it would have done. But had I logged in on the Sun Ray 150 first there may have been a problem. Therefore you may need to set your preferred default resolution to the largest available value to allow for that growth. This is accomplished using utxconfig:

$ /opt/SUNWut/bin/utxconfig -r 1920x1200

So what of automatic switching?

Taking Chris' Sun Ray location idea a little further I re-wrote his script, ut-where, so that it automatically switches the display depending on the device setting. This modified script has a couple of other new features including

  • Pops up a window asking for the location if it's not known using zenity(1) (times out after 5 mins if you don't answer).
  • Sets your status as un-available if the location description includes the word "conference".
  • May be used to start IM client and monitor clients using the -i option.
  • As before sets your away status when you disconnect (remove your card), unless that is you have already set your status to away... Great when you want to set your away status to something descriptive before leaving.

I'm still toying with the idea of saving other preferences to the location file such as the preferred resolution and or pidgin status... Full options listed below.

$ ut-where -h
usage: ut-where [-vxX][[-i]|[-d]|[-s]|[-t]|[-l]|[-c]|[-a [description]]]

  -a	Add location, prompts for description if none supplied.
    	Colon characters in description are substituted by space character.
  -l	Display contents of location file.
  -i	Initialise; starts utaction monitors for connect/disconnect
    	Will also start IM client if none active for user.
    	Kills current "utaction ut-where" scripts
  -c	Update pidgin with current description:
    	This option is intended to be used by "utaction -c"
    	If description is unknown then a description dialogue is
    	requested using zenity.
    	If description contains "conference" then status is
    	set to "unavailable".
  -d	Update IM tool with away message (unless away status already set).
    	This option is intended to be used by "utaction -d"
  -t	Display current description.
  -v	Verbose mode
  -x	Debug
  -X	Debug functions

Without any options the appliance name and description are displayed.
$

Thus to start IM client and utaction monitors simply use ut-which -i.

One final note. I have found some devices have there default resolution set much lower than expected, i.e. 640x480. Therefore you may need to change those. The best way to do that is to use utsettings (press <shift>-<props> keys together) and change the resolution under the "Display" category.

Happy switching.

Wednesday Oct 29, 2008

When interacting with a window interface I prefer point-to-focus rather then click-to-focus. This can easily be achieved by enabling "Select Windows when the mouse moves over them" from "Window Preferences" (from Gnome Preferences).

But I also prefer my windows to stay put and not atomically raise to the top when I click in them, for example when using middle-click to paste into the obscured window...

To stop that annoying behavior run 'gconf-editor' and enable the Sun Extension 'window_raise_on_frame_only', /apps/metacity/general/sun_extensions/window_raise_on_frame_only (use ctrl-F and search for it). The associated note for which states "If enabled, in sloppy focus mode [point-to-focus], the window will be raised to top of stack when clicked on window frame only. Windows will not raise when clicked inside them." Sloppy in deed, how dare you ;-)

Previously I have unset /apps/metacity/general/raise_on_click which also worked for me. Though it does contain the following description underneath it:

"Setting this option to false can lead to buggy behavior, so users are strongly discouraged from changing it from the default of true. Many actions (e.g. clicking in the client area, moving or resizing the window) normally raise the window as a side-effect. Set this option to false to decouple raising from other user actions. Even when this option is false, windows can still be raised by an alt-left-click anywhere on the window, a normal click on the window decorations, or by special messages from pagers, such as activation requests from tasklist applets. This option is currently disabled in click-to-focus mode. Note that the list of ways to raise windows when raise_on_click is false does not include programmatic requests from applications to raise windows; such requests will be ignored regardless of the reason for the request. If you are an application developer and have a user complaining that your application does not work with this setting disabled, tell them it is _their_ fault for breaking their window manager and that they need to change this option back to true or live with the bug they requested. See also http://bugzilla.gnome.org/show_bug.cgi?id=445447#c6."

I do wonder if the above warning does also apply to window_raise_on_frame_only?

Sunday Jan 13, 2008

ublog test

Friday Oct 05, 2007

Today I came across the OpenSolaris Project: Starter Kit which includes links to OpenSolaris Screencasts (videos).

In particular I like the reference to the backup tool "g4u" to backup my Windows partition(s). It would be neat if I could use the same trick to backup the Solaris partition too.

Thursday Sep 27, 2007

Peter tagged me! I'm like the school boy who, while lining up in the playground to play one game, is suddenly rushed upon and touched in a fleeting moment to the cheer of "tag" as the ascendant races off. I liked playing tag, though I always preferred "Stuck in the mud" (apparently known as Freeze Tag in some places).

So, five things you may not already know about me....

  1. Thinking that I may have had a very minor dairy intolerance I gave up eating dairy produce in my early twenties. Obviously this means no Milk, Cheese or Chocolate. But that's only the half of it. Wey solids and powder are found in an amazing host of foods like biscuits, cakes and crackers. And all those really nice things like cakes (did I say that already), custard, pastries, and a whole lot more.... I'm not sure the diet had much effect on my Asthma, but I sure did put on the pounds once I came off of it (I have subsequently lost that weight, with help from the Hackers Diet) and my bicycles. I was certainly glad to no longer be having water on my morning cereal.

  2. This may not be so surprising to those paying close attention to my blog... OK, so its a surprise to you all! I used to be cleaner at Express Dairies. It helped me save up for the road "racing" bicycle that I still ride to this day. My section included a small hall with a free milk dispenser which was always in a real slimy and smelly state come the evening (people, be considerate with your unwanted beverages). I still remember with joy the first time I used the floor polishing machine. It whizzed around taking me with it and wrapping me around with the power cord. Took a few times to tame it, but it was always fun.

  3. Somewhat like Clingan at school I was interested in long distance running. I used to take part in the cross country race each year and for sports day entered the 1500m and 5km race. Though I never took it seriously, I just seemed to have a lot of stamina. These days I really don't enjoy running and much prefer to be on my bike where my stamina still sees me through..

  4. I was in a Secondary School (high-school) production of "My Fair Lady". I was in the chorus and several non-speaking parts including a chimney sweep and ballroom dancer. I enjoyed every moment of it, especially learning the waltz (shame I don't remember it now). I dare say it's those memories why I encourage my girls to take up the thespian joys that they have. Mind, they can sing unlike myself.

  5. On the theme of Musicals, my favorites all time is the film "The Slipper and the Rose", staring Richard Chamberlain and Gemma Craven. It is in my opinion the best adaptation of the Cinderella Story. My favorite bit is when the fairy god mother, played by Annette Crosbie, exclaims "I know, I'll borrow time!" (or something to that effect) which for me explained why the magic had to be withdrawn at midnight. So why don't the slippers disappear? Well that magic clearly wasn't borrowed ;-)

So, Jonathan, your it!

Stace

This blog copyright 2009 by ace