Getting insights with DTrace - Part 2

OS version checks (uname)

Introduction / Motivation

DTrace is not just able to monitor / view things. Adding a special pragma statement, it is even possible to overwrite / modify values. Within this chapter you will find an unsupported use-case:
run software doing hard coded OS version checks on newer OS versions (like OpenSolaris).

Background

In case you are interested in playing around with SAP on OpenSolaris, you will encounter SAP error messages which are due to the fact, that your SAP kernel has not been released for SunOS 5.11. If you query disp+work, you will see something like:

solman:demadm 6% disp+work

--------------------
disp+work information
--------------------

kernel release                700
kernel make variant           700_REL
compiled on                   SunOS 5.9 Generic_117171-13 sun4u
compiled for                  64 BIT
compilation mode              UNICODE
compile time                  Feb  3 2008 21:08:24
update level                  0
patch number                  146
source id                     0.146

---------------------
supported environment
---------------------

database (SAP, table SVERS)   700
                              
operating system
SunOS 5.9
SunOS 5.10
solman:demadm 6%
Recently Updated
by joerg_meiners (29 Jan)
Adaptive Oracle Grid (SAPonSun)
by j.brosowski (28 Jan)
Understanding a SAP SD 2-tier benchmark result (SAPonSun)
by vwetter (19 Jan)
Open Dodecaeder for SAP on Sun (SAPonSun)
by j.brosowski (18 Jan)
Open Dodecaeder for SAP on Sun v. 16 (SAPonSun)

If you try to logon to SAP, you will see error messages indicating a problem in your setup. Running the SAP Initial Consistency Check transaction (SICK), you will see:


In order to get rid of this message on a sandbox system (!!), it seems to be appealing to fake the Solaris version. There are also software packages that check the OS version during installation and exit without installing the software in case the OS version differs from expected values. This is partially true also for Oracle's runInstaller. However, this tool provides options to bypass tests for prerequisites by using the parameter '-ignoreSysPrereqs'. But back to SAP SICK problems. How can DTrace help ?

Solution

The system call that is used to determine the OS version is 'uname' (not the Solaris 'uname'-command). So let's start with a very basic and easy script which uses the entry probe of this system call. The provider we are going to use is called 'syscall':

The predicate /uid == $1/ will make sure, that only uname calls executed by the specified userid will be caught.
But that's just the start. The script to overwrite the OS version is listed below:

#!/usr/sbin/dtrace -s
#pragma D option destructive

/*
* Disclaimer:
* Use at own risk !
* Don't try this at work !
* this script may be used in sandbox environments to
* pretend a different Solaris version to a specific
* OS user. By changing the predicate it is possible 
* to filter other processes like the ones within a
* specific zone, a specific project etc.
* The builtin curpsinfo struct might be your friend
*/

struct utsname myuts;

syscall::uname:entry	
/uid == $1/
{
	self->uts_name_addr = arg0;
}

syscall::uname:return	
/uid == $1/
{
	rel_size = sizeof(myuts.release);
	rel_offset = offsetof(struct utsname, release);
	copyoutstr("5.10", self->uts_name_addr+rel_offset, rel_size);	
}

The statement '#pragma D option destructive' explicitely allows data modification. We still have an entry probe on uname, just because we need to save the pointer to a struct containing the OS version, which is the first argument to uname. This struct is called utsname. You can find details about this struct in sys/utsname.h:

struct utsname {
        char    sysname[_SYS_NMLN];
        char    nodename[_SYS_NMLN];
        char    release[_SYS_NMLN];
        char    version[_SYS_NMLN];
        char    machine[_SYS_NMLN];
};

We are particularly interested in the third field with name 'release'. In order to acces that field within the return probe, we have to use the pointer to the utsname struct (saved in the thread local variable uts_name_addr) and apply the corresponding offset.
For the same reason we have been using the copyinstr command before, we have to use the copyoutstr command now: DTrace runs within kernel context and cannot access the application context directly.
In case you want to change the OS version for all processes within a given zone (passed as argument), just replace the two predicate lines by:

/curpsinfo->pr_zoneid == $1/

After running the DTrace script and starting SAP, we want to check transaction SICK again:

SAP is no longer reporting an unsupported OS. Well, DTrace is certainly a good argument not to complain.

Labels

sap sap Delete
opensolaris opensolaris Delete
dtrace dtrace Delete
uname uname Delete
favourite favourite Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

Sign up or Log in to add a comment or watch this page.


The individuals who post here are part of the extended Sun Microsystems community and they might not be employed or in any way formally affiliated with Sun Microsystems. The opinions expressed here are their own, are not necessarily reviewed in advance by anyone but the individual authors, and neither Sun nor any other party necessarily agrees with them.

© 2010, Oracle Corporation and/or its affiliates
Powered by Atlassian Confluence
Oracle Social Media Participation Policy Privacy Policy Terms of Use Trademarks Site Map Employment Investor Relations Contact