Saturday October 03, 2009 | Artem's Weblog |
|
New in 124: physical eject button OpenSolaris build 124 is out and includes a new feature: now you can use the eject button on your CD/DVD drive to eject the disc, even if it is mounted. To quote the heads-up message: Pressing Eject button on CD/DVD drive's front panel will have the same effect as typing 'eject' in the terminal or clicking the corresponding GUI icon in the File Browser. Most modern drives support this feature, though some older ones don't. You may see a harmless pop-up message "Unable to unmount volume" due to GNOME bug 9805. It can be safely ignored, but if it bothers you, the workaround is: svccfg -s rmvolmgr setprop rmvolmgr/eject_button=boolean: false svcadm restart rmvolmgr The side effect of the workaround is being able to use physical eject button only with a GNOME session running, not when logged into the text console. Aside from the issues listed in the build notes, be aware of the "Console User" problems. If you are curious about how the eject button works in OpenSolaris, read ARC case 2009/058. It is quite remarkable that Solaris managed to go without this capability for so long: other OSes have had it for years. I should have fixed it as part of the Tamarack project, but had to sacrifice some features to meet the schedule. I then switched to networking projects, and the feeling of unfinished business has been nagging me ever since. Walking around with a solution to a problem in your head is, I imagine, not unlike being pregnant: you cannot carry it inside forever. I knew how, I had the code visualized mentally. It was a great relief when one evening I finally initiated the mind->computer transfer. The hard part was to properly test the code: too much weird or buggy hardware out there. All of the PCs, x86 laptops and recent Sun products worked just fine. I did encounter some old Sun gear that did not support the eject button - for those, the eject(1M) command continues to be the only option. I'd like to thank Neal, Phi and Larry for their help with the last mile effort. (2009-10-03 12:20:08.0) Permalink Comments [3]My little Solaris security cheat sheet This returned me to sanity a few times while learning about Solaris security. Like many others, I'm not a security expert and I often need a short version to fit in my head. authorization A right assigned to users that is checked by privileged programs to determine whether users can execute restricted functionality. More in auth_attr(4). privilege An attribute that provides fine-grained control over the actions of processes, as opposed to traditional unix all-or-nothing, super-user vs user, model. More in privileges(5). profile A logical grouping of authorizations and commands. Profile shells, pf[ck]sh, interpret profiles to form a secure execution environment. More in prof_attr(4), exec_attr(4). role A type of user account, with associated authorizations and profiles. Roles cannot be logged in directly - users assume roles using su(1M).
1Was also available much earlier in Trusted Solaris. Tags:
Solaris
OpenSolaris
Security
Free Code Graphing Project was an attempt to visualize Linux kernel source code. Now that Solaris is free code, too, why not try to graph it. This blog entry describes my little effort of debugging the thing into existence. I can't afford to spend any more time on this, so hopefully someone picks the baton. The end result is a huge PostScript file that looks like this:
Sample close-up, common/vm/seg_kmem.c:
Roughly, the algorithm used:
Here's how rings are defined for Linux: RING1:=init lib mm kernel ipc RING2:=net fs RING3:=$(subst $(KERNEL_DIR)/,,$(wildcard $(KERNEL_DIR)/arch/*)) RING4:=drivers crypto sound security Solaris has a bit different directory structure. Here's what I used: RING1:=common/os common/vm common/c2 common/cpr common/disp common/dtrace common/exec common/krtld common/syscall RING2:=common/fs common/inet common/ipp common/ktli common/rpc RING3:=i86pc sparc sun sun4 sun4u sun4v RING4:=common/io Steps to make it work in Solaris 1. Prerequisites:
2. Set you KERNEL_DIR environment variable to usr/src/uts subdirectory of OpenSolaris source, e.g.: KERNEL_DIR=$HOME/solgraph/usr/src/uts; export KERNEL_DIR 3. Preprocess OpenSolaris code, since the fcgp parser does not like Solaris coding style (ignore warnings):
chmod -R +w $KERNEL_DIR
find $KERNEL_DIR -name '*.c' -exec indent -npsl {} \;
4. Modify your path to look in /usr/xpg4/bin first: Alternatively you can replace all 'tail -n number' occurences in fcgp scripts with 'tail -number', but it's easier to just use /usr/xpg4/bin/tail. PATH=/usr/xpg4/bin:$PATH; export PATH 5. If using X, turn off the bell. Fcgp spits out some escape sequences that would drive you nuts (they might not look pretty on some terminals either): xset -b 6. Kick off the build process. Takes about 9 minutes on my Ferrari 3400. cd lgp-2.6.0a-solaris gmake CC=gcc 7. Generate viewable/printable postscript files. Examples for a single file and for a 6x6 poster: ./posterize a4 1 ./posterize a4 6 See README for more information on printing and assembling a poster. To do list
I won't have time for these in the next two months, so feel free to pick up where I left. I can be reached at artem dot kachitchkin at sun dot com. Tags:
Solaris
OpenSolaris
A minor instance of driver confusion Most driver writers are familiar with device minor numbers. But a notion of an instance number is specific to Solaris and it is often incorrectly assumed that minor == instance. Let's see if we can see clear that up. Instance number A driver handles devices of a certain type. There can be multiple instances of the same device type in the system. For example, there are two asynchronous serial devices (UARTs) on my system, handled by the asy(7D) driver and represented by two nodes in the device tree:
$ prtconf -D | grep asy
asy, instance #0 (driver name: asy)
asy, instance #1 (driver name: asy)
These are the two instances of the same driver: sharing binary code in the kernel address space, but maintaining separate data 1. Instances are numbered, in this case 0 and 1. Instance numbers are assigned permanently to physical devices in the system; the mapping is maintained in the /etc/path_to_inst file:
$ grep asy /etc/path_to_inst
"/isa/asy@1,3f8" 0 "asy"
"/isa/asy@1,2f8" 1 "asy"
There are also drivers without respective hardware, called pseudo drivers. An example of a pseudo driver is random(7D), the random number generator driver. Pseudo drivers have no physical device nodes to attach to. We have to synthesize artificial instances via driver.conf file:
$ cat /kernel/drv/random.conf | egrep -v '^#|^$'
name="random" parent="pseudo" instance=0;
The system obeys and creates a node for instance 0:
$ prtconf -DP | grep random
random, instance #0 (driver name: random)
Drivers can retrieve their instance number with ddi_get_instance(). Minor number Outside the kernel, devices are identified by their {major, minor} pairs, also know as dev_t. The major number range is owned by the system. It assigns major numbers when drivers are installed and keeps the list in /etc/name_to_major:
$ grep asy /etc/name_to_major
asy 106
The minor number range is owned by the driver. A minor number becomes visible to the userland when the driver creates a minor node using ddi_create_minor_node() 2, which takes minor number as one of its arguments:
int ddi_create_minor_node(dev_info_t *dip, char *name, int
spec_type, minor_t minor_num, char *node_type, int flag);
Problem is, the minor number range is shared among all driver instances, so each instance can only use a subrange. If each instance needs exactly one minor node, then the node's minor number can equal instance number, i.e. the 4th argument in ddi_create_minor_node() is set to instance number. Things get a bit fancier in case of multiple minor nodes per instance. Serial drivers typically create two nodes per node: one in /dev/term and one in /dev/cua:
$ ls -lL /dev/{term,cua}/[ab]
crw------- 1 uucp uucp 106, 131072 Jun 29 19:04 /dev/cua/a
crw------- 1 uucp uucp 106, 131073 Jun 29 19:04 /dev/cua/b
crw-rw-rw- 1 root sys 106, 0 Jun 29 19:04 /dev/term/a
crw-rw-rw- 1 root sys 106, 1 Jun 29 19:04 /dev/term/b
106, as we saw earlier, is asy major number. Minor numbers 0 and 131072 (0x20000) belong to instance 0, and 1 and 131073 (0x20001) to instance 1. The instance/minor mapping is not 1:1 here. Conversion The driver holds the algorithm for mapping instances into minors and vice versa. When the kernel needs to find out instance number from a minor number, it has to ask the driver by calling getinfo(9E) entry point with the DDI_INFO_DEVT2INSTANCE command. One example could be found in spec_open() which calls e_ddi_hold_devi_by_dev(). 1 Per-instance data is called soft state and explicitly supported in DDI, see ddi_soft_state(9F) man page. 2 A whole lot of action can be triggered by ddi_create_minor_node(). See dacfc_match_create_minor() and /etc/dacf.conf file on your nearest Solaris system. Tags:
Solaris
OpenSolaris
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||