Seth Miller

Technical ramblings of an IT guy

Replacement Menu Script for Oracle’s oraenv

This script is a replacement for the “oraenv” script used to set the server environment on an Oracle database server. It’s biggest advantage over oraenv is that it requires far fewer keystrokes and provides a lot more feedback.

I’ve been using various versions of this script for years but I decided to put together a version that can run on its own so it can be shared.

To use it, execute the script once in your session and type “db” (which will call the function) each time you want to change the environment.

Enterprise Manager 12c EMCLI Target Properties and Metadata

This post refers to Enterprise Manager 12c Release 3 specifically but much of the information applies to earlier releases. The EMCLI command examples are using the Jython interactive interface. Examples are sometimes shown on multiple lines for clarity and may need to be on the same line to work properly.

Most of the Enterprise Manager Command Line Interface (EMCLI) verbs have a “properties” parameter that consists of one or more (delimited by a semi-colon by default) name-value pairs (delimited by a colon by default). This “properties” parameter can mean different things depending on what verb you are using.

This post will use the “add_target” verb as an example. The documentation defines the “properties” parameter for the “add_target” verb as:

Name-value pair (that is, prop_name:prop_value) list of properties for the target instance. The “name”(s) are identified in the target-type metadata definition. They must appear exactly as they are defined in this file. Metadata files are located in $AGENT_HOME/sysman/admin/metadata.

The last sentence specifying where the metadata files are located is simply not true but is a rough interpretation of where the files are. Let’s assume the 12c agent was installed in a base directory called “/u01/app/oracle/product/12.1.0/agent12c”. All of the plugins would be installed in the “plugins” subdirectory of the base directory. The “metadata” directory would be a subdirectory of the plugin and the files contained within that directory pertain to the target types.

Base Directory = /u01/app/oracle/product/12.1.0/agent12c
Plugins Directory = /u01/app/oracle/product/12.1.0/agent12c/plugins
Database Plugin Directory = /u01/app/oracle/product/12.1.0/agent12c/plugins/oracle.sysman.oh.agent.plugin_<version>
Database Plugin Metadata Directory = /u01/app/oracle/product/12.1.0/agent12c/plugins/oracle.sysman.oh.agent.plugin_<version>/metadata
Database Instance Metadata File = /u01/app/oracle/product/12.1.0/agent12c/plugins/oracle.sysman.oh.agent.plugin_<version>/metadata/oracle_database.xml

Where the documentation is a little more accurate (but not really) would be for the “host” target type. Since the “host” target type does not use a plugin, it is located in the “core” directory.

Base Directory = /u01/app/oracle/product/12.1.0/agent12c
Core Directory = /u01/app/oracle/product/12.1.0/agent12c/core/<version>
Core Metadata Directory = /u01/app/oracle/product/12.1.0/agent12c/core/<version>/sysman/admin/metadata
Host Metadata File = /u01/app/oracle/product/12.1.0/agent12c/core/<version>/sysman/admin/metadata/host.xml

Many of the verbs (including add_target) requires that the “Oracle Home” be specified in the properties parameter. When adding or modifying targets in the UI, this property appears on the “Monitoring Configuration” page.

target_properties_1

However, when specifying the Oracle Home property in the add_target verb, the name of the property is “OracleHome”.

add_target(
name='ORCL1_RAC1',
type='oracle_database',
host='rac1.example.com',
properties='
  SID:ORCL1;
  Port:1521;
  OracleHome:/u01/app/oracle/product/11.2.0/dbhome_1;
  MachineName:rac1.example.com',
credentials='
  Role:normal;
  UserName:dbsnmp;
  password:password') 

To find the correlation between the property in the UI and what is specified in the EMCLI verb, we need to (as the documentation specifies) look into the “metadata” files of the agent. What isn’t clear from the documentation is that there are multiple places in the agent binaries where “metadata” files are found.

The example given above is for an “oracle_database” target type. Since the monitoring of Oracle database targets are now done with a plugin, the “$AGENT_HOME” actually means the Oracle database plugin home in this case.

The metadata files have “.xml” or “.xmlp” file extensions. The target type of “oracle_database” is in the “oracle_database.xml” file. These files are not very well commented so having a basic understanding of XML is required. The relevant information is usually toward the bottom but it is easiest to just search for the opening XML tag called “<InstanceProperties>”. For some target types, the XML elements we are looking for will be nested within the “<InstanceProperties>”. But, for others (like this one), they will be referenced from another location.

  <InstanceProperties>
        &inst_static_props;
        &dynamic_properties;
        &esa_inst_dynamic_properties;
        &esa_db_dynamic_properties;
        &inst_dynamic_props;

  </InstanceProperties>

In this case, the information we are looking for is not directly inside the “<InstanceProperties>” element. When the XML parser finds an ampersand in the XML data, it expects to find a symbol name and a semicolon following it. The symbol name provides a symbolic reference to another entity. A quick search on this symbolic reference finds that the information is actually stored in another file.

<!DOCTYPE TargetMetadata  [
<!ENTITY inst_static_props SYSTEM "./inst_properties.xmlp">
<!ENTITY inst_dynamic_props SYSTEM "./inst_dynamic_props.xmlp">

...

<!ENTITY dynamic_properties SYSTEM "./dyn_props.xmlp">
<!ENTITY esa_inst_dynamic_properties SYSTEM "./esa_instance_dyn_props.xmlp">
<!ENTITY esa_db_dynamic_properties SYSTEM "./esa_database_dyn_props.xmlp">

...

]>

The “inst_properties.xmlp” file contains the elements we are looking for. Each verb property is specified in an “<InstanceProperty>” element. The element uses a combination of tags and nested elements to define the verb property.

<InstanceProperty NAME="OracleHome" CREDENTIAL="FALSE" OPTIONAL="FALSE">
        <Display>
                <Label NLSID="OracleHome_iprop">Oracle home path</Label>
        </Display>
</InstanceProperty>

The first tag called “NAME” is what is used as the property name in the verb. The “CREDENTIAL” tag set to “TRUE” means that the property would be specified in the “credentials” verb parameter, not the “properties” parameter. The “OPTIONAL” tag set to “TRUE” means the property is not necessary and will likely have a default value if not specified. The “IS_COMPUTED” tag set to “TRUE” means that the parameter is dynamically calculated. The “Label” element will give you a good idea what property matches in the UI monitoring configuration page but it usually does not map directly. Not all of the properties specified in the XML file will show up in the UI configuration either.

From the information in this file, we can tell that the “properties” (they are case sensitive) that must to be specified for the “oracle_database” type are:

  • OracleHome
  • MachineName
  • Port
  • SID

The “properties” that can be optionally specified are:

  • PreferredConnectString

The “credentials” that must to be specified are:

  • UserName
  • password

The “credentials” that can be optionally specified are:

  • Role

Much of the configuration information in Oracle’s products (especially Enterprise Manager) is stored in XML. Having a basic understanding of the XML structure helps a lot in identifying the information you are looking for. The information used in the “properties” and “credentials” parameters for many of the verbs in the Enterprise Manager CLI can be found in the metadata files within the agent binaries. Knowing where to look and what to look for is the most important step.

Oracle OpenWorld 2013 and RAC Attack

Less than a week from now I will board a plane destined for San Franscisco, California for my favorite week of the year. More than 60,000 people will descend on The City by the Bay to build a city block long tent over Howard Street and make the local commuters miserable.

This year marks my third year in a row attending Oracle’s largest event and my second year as a speaker. I have the honor of speaking on two panels on User Group Sunday; DBA Expert Panel and Oracle Enterprise Manager Panel alongside some of the most respected technologists in the Oracle technical community.

Last year at OpenWorld, I stumbled into a quiet room of geeks slumped over their laptops; some typing furiously, others staring blankly at a screen, searching for an answer. After seeing the all-to-familiar Oracle Database installer window, I realized that this was a good old fashioned Installfest. I was soon approached by an organizer who asked me if I have ever installed Oracle RAC before. I had done it many times, of course as part of my job, but I couldn’t recall ever doing it just for fun. This event was alliteratively called RAC Attack. I immediately took interest in becoming involved after working with this group at OpenWorld last year, and soon after became a contributor and volunteer.

RAC Attack is a group of very smart volunteer technologists who contribute their valuable time to introduce people to Oracle RAC. They do this by creating the guides featured on the website and hosting onsite installfests. RAC Attack is now featured at almost every major Oracle sponsored and Oracle related event around the world.

RAC Attack will be running from 10am until 2pm on Tuesday and Wednesday at the OTN Lounge in Moscone South. It’s not formal so feel free to stop by any time. If the laptop you are carrying is not powerful enough to run a couple of beefy virtual machines, we will have a number of laptops and desktops that you can use. If you are already a RAC Ninja, stop by and help get the newbies hooked on Real Application Clusters.

Yury Velikanov has taken the lead for us on the planning for this year’s event. Further details about RAC Attack at OpenWorld 2013 can be found at his blog.

RAC Attack has a Google+ page and a Facebook page.

Tablespace Size Report Script (updated)

I actually found it a little difficult to find a good sql script for reporting tablespace size so I took one that was almost there which I believe came from Oracle-Base and modified it to fit my needs. Feel free to comment or modify.

Update: I’ve made significant changes to this script including a header and the ability to change the output denomination between megabytes, gigabytes or terabytes with a simple script parameter. Take a look at the notes in the script for more details.

Monitor NFS I/O

We use RMAN to backup to an NFS share. I was having some very lengthy RMAN backup times during certain time periods and the storage team was not able to correlate the slow downs to anything useful so I decided to monitor the NFS shares.

I looked at the OS Watcher logs for information about NFS, but they were severely lacking in useful information. The program nfsiostat had the information I was looking for but I wanted to collect information over different periods of time so cron was naturally the best way to schedule the collections.

However, like vmstat, iostat and most other programs of this nature, when executed, nfsiostat shows a summary since the last boot as its first iteration. Since I am not interested in the summary, I needed a way to exclude that first iteration. What better way to do line processing than to use the 40+ year old tool awk.

Finding what text to use as the separator between the iterations was easy since the first line of each iteration ends with the nfs mount I’m filtering on. I set the first parameter in the file as the mount point. The command will be executed twice, one second apart, the first being the throw-away summary and the second being the information I want to keep. There is a timestamp captured as well for each execution.

The output is captured in a file.

#!/bin/bash


NFS_IO_STAT_TARG="/backup"
NFS_IO_STAT_PARMS="1 2"
NFS_IO_STAT=/usr/sbin/nfsiostat
NFS_IO_OUT=~/nfsiostat_$(hostname -s).out
TIMESTAMP=$(date +%F_%R)_$(hostname -s)


(
echo -e "\n$TIMESTAMP\n"
$NFS_IO_STAT $NFS_IO_STAT_PARMS $NFS_IO_STAT_TARG | awk 'BEGIN { VAR="'$NFS_IO_STAT_TARG':$" } $0 ~ VAR { ccount++ }; ccount >= 2 { print }'
echo ====================================================
) >> $NFS_IO_OUT

Tnsnames.ora and XML Solution

I have always found the Oracle connection strings (typically tnsnames.ora) difficult to manage. Even when using LDAP instead of the file, the connection strings still need to be managed even though it only has to be done in one place. After some planning and learning (and relearning) some atrophied perl skills, I created a set of scripts to manage the Oracle connection strings using XML and perl.

If you look at the Oracle connection string, it looks a lot like XML. Instead of tags using the format

<ELEMENT>foo</ELEMENT>

it uses

(foo)

I converted the existing tnsnames.ora to XML using Vim’s search and replace and a whole lot of regexp. After converting the file and having a parseable XML file, I realized that the possibilities with this are endless. It doesn’t have to be limited to just the connection strings, a single database entry can contain any amount of information you might want to track with each database. But, we’ll get to more of that later.

Here is what an Example XML entry will look like.

The script requires certain elements to properly function. I will detail them here using XPATH syntax. I have chosen /TNSNAMES as the root but it doesn’t really matter what you use. The required children are as follows:

TNS[@NAME=""]
TNS/DESCRIPTION/ADDRESS_LIST/ADDRESS
TNS/DESCRIPTION/CONNECT_DATA
TNS/DESCRIPTION/CONNECT_DATA/SERVICE_NAMES/SERVICE_NAME[@ID="1"]

There are many more options to add to an Oracle connection string, and there will be additional functionality added in future releases but for now, these additional paths are optional.

TNS/DESCRIPTION/*
TNS/DESCRIPTION/CONNECT_DATA/INSTANCES/INSTANCE[@ID="1"]

The INSTANCES/INSTANCE[@ID=”1″] was added because I am using this script to create multiple entries for the same connection to be used in the Oracle wallet for different users. When I am connecting as the SYS user to a database to change the password, I am specifying that I want to connect to (CONNECT_DATA(INSTANCE=ORCL1)) so that I know which password file is being changed, therefore making it easy to then copy that changed password file to the rest of the nodes in a cluster. The script is shown here and is being hosted on GitHub. The script, the example XML file above and the result file below are all directly linked to GitHub and will change as updates are made.

Details on how to use the script can be found in the script and listed using the help flag for brief information and the man flag for the full documentation.

This shows what the XML example file above looks like after being parsed using no script options.

I will update this post with usage examples and details of additional functionality as it is added.

I have also written another script that parses the same XML format but the output produces a connections file that can be loaded into Toad. I have my install of Toad set up to use an Oracle wallet that I have populated with all of the database passwords that I use. I use the parser script to produce both the tnsnames.ora that I am using for the connection strings as well as the connections text file that I loaded into Toad to match. I call this script ToadBuilder and I will load it into GitHub as well. I haven’t decided if I will combine the two scripts yet or not since there is a lot of repeated code but I don’t want the script options to become too complicated.

Please feel free to post feedback or contribute to the scripts. I am an amateur with perl and improvements are very much welcome.

How Far Back Can I Flashback My Database To?

Flashback Database
Here is a useful query to find out the current limit of flashback database. Change the ‘US/Central’ to your local time zone to convert the time zone your database is in to your local time zone.

The first column is the earliest point in time you can flashback the database to. The second column is the number of hours between now and the earliest point in time you can flashback your database to truncated to one decimal point.

select cast(
            from_tz(
                    cast( oldest_flashback_time as timestamp )
                   ,dbtimezone )
            at time zone 'US/Central' as date ) oldest_db_fb
       ,round((sysdate - oldest_flashback_time) * 24, 1) oldest_db_fb_hours
  from v$flashback_database_log;

SyntaxHighlighter Bash Edits

I installed the SyntaxHighlighter Evolved plugin to better display code in my blog posts. I will be going through old posts and updating them so that any code that is not pulled directly from GitHub uses it.

I’m not a web developer so if I sound like a novice, it’s because I am. I made these edits by looking at examples and copying the work of others. I welcome feedback and corrections.

I generally use the Bash/Shell brush but found it lacking a few features that are pretty basic when looking at shell code so I’ve added them to my templates.

I usually include the shell prompt in my code boxes to differentiate between commands but find it painful when I am trying to select from someone’s code snippet and have to select “around” the prompts so I added a css context that disallows a select and made all of my prompts use that context. Here’s an example. Try to select the code in this box and paste it somewhere else.

[root@shell prompt ~]# The prompt is not selectable but this text is.

There are two parts to this. One is the css piece that I just added into the shThemeDefault.css.

.syntaxhighlighter .bashprompt {
  color: brown !important;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

The second part is the addition of the third line to the shBrushBash.js javascript brush file.

		this.regexList = [
			{ regex: /^#!.*$/gm,											css: 'preprocessor bold' },
			{ regex: /^\[[^\]]+]# ?/g,										css: 'bashprompt' },
			{ regex: /\w+==?/g,												css: 'variable' },
			{ regex: /\/[\w-\/]+/gm,										css: 'plain' },
	//		{ regex: SyntaxHighlighter.regexLib.singleLinePerlComments,		css: 'comments' },		// one line comments
			{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,			css: 'string' },		// double quoted strings
			{ regex: SyntaxHighlighter.regexLib.singleQuotedString,			css: 'string' },		// single quoted strings
			{ regex: new RegExp(this.getKeywords(keywords), 'gm'),			css: 'keyword' },		// keywords
			{ regex: new RegExp(this.getKeywords(commands), 'gm'),			css: 'functions' }		// commands
			];
	}

It is a regular expression that says; look for a left bracket at the beginning of the line followed by one of more characters that are not right brackets, followed by a right bracket and a pound sign and zero or one space and assign the whole thing to the bashprompt css context.

There are two other things I have changed so far. I commented out line six which is the one line comment because it was messing with my root prompt and I added line four for highlighting variable assignments.

		this.regexList = [
			{ regex: /^#!.*$/gm,											css: 'preprocessor bold' },
			{ regex: /^\[[^\]]+]# ?/g,										css: 'bashprompt' },
			{ regex: /\w+==?/g,												css: 'variable' },
			{ regex: /\/[\w-\/]+/gm,										css: 'plain' },
	//		{ regex: SyntaxHighlighter.regexLib.singleLinePerlComments,		css: 'comments' },		// one line comments
			{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,			css: 'string' },		// double quoted strings
			{ regex: SyntaxHighlighter.regexLib.singleQuotedString,			css: 'string' },		// single quoted strings
			{ regex: new RegExp(this.getKeywords(keywords), 'gm'),			css: 'keyword' },		// keywords
			{ regex: new RegExp(this.getKeywords(commands), 'gm'),			css: 'functions' }		// commands
			];
	}

Oracleasmlib Not Necessary

Not only is it not necessary, but it may not even be available. This is in fact exactly what I discovered recently when I installed the Oracle Linux 6u3 and tried to install Clusterware on it.

There are three packages that one would normally install as part of ASM:

  • oracleasm-$( uname -r ) # Kernel driver
  • oracleasmlib # ASM libraries
  • oracleasm-support # Support scripts

In Oracle Linux 6, the driver is built into the kernel so it is no longer necessary to install the first item in the list. The OTN site for ASM claims that the

“oracleasm-support and oracleasmlib packages still need to be installed from ULN.”

However, say you are like me and too lazy to try to get the necessary credentials out of the Unix team for access to ULN and you therefore use the publically available yum repository. The Oracle Linux 5 “Latest” repo has the oracleasm-support packages and the oracleasm kernel drivers for each kernel released for that version. In the Oracle Linux 6 “Latest” repo, only the oracleasm-support packages are there. The oracleasmlib packages are not in any of the public yum repositories. The oracleasmlib package is available for all versions in ULN though as well as a manual download as this OTN note clarifies.

“While the driver and support tools are on the Oracle Linux installation media, the oracleasmlib RPM is not (this package allows Oracle to access the kernel driver). This package is only available on ULN. Subscribers to ULN can use yum(8) or up2date(8) to download and install the package on their servers. Non-subscribers are free to use the similar package built for RHEL on their Oracle Linux machines. New ULN subscribers that happen to be using the RHEL version of the oracleasmlib package are advised to update the package from ULN.”

In other words, if you want oracleasmlib and you don’t have access to ULN, you can download the RPM manually from here. Make sure to download the one that matches your architecture (x86 or x86_64).

Once you have an ASM disk created through oracleasm, there are two ways to test it to make sure it works. One is to use a program that is included in the oracleasmlib package called oracleasm-discover. Running oracleasm-discovery will show a simple text output similar to the following.

[root@generic ~]# oracleasm-discover
Using ASMLib from /opt/oracle/extapi/32/asm/orcl/1/libasm.so
[ASM Library - Generic Linux, version 2.0.4 (KABI_V2)]
Discovered disk: ORCL:DATA1 [192717 blocks (98671104 bytes), maxio 512]
Discovered disk: ORCL:DATA2 [1012032 blocks (518160384 bytes), maxio 512]

You’ll notice that this is using the 32 bit library. The OS that I tested this on is 64 bit and I spent a lot of time wondering why I could see the disks with oracleasm-discover but not with asmca until I came across MOS article 1444115.1. Under Case #1, there is a note about using the wrong library. I uninstalled the 32 bit version and installed the 64 bit version. oracleasm-discover still works but this time I was also able to see the disks in asmca.

[root@generic ~]# rpm -ev oracleasmlib

[root@generic ~]# rpm -ivh http://download.oracle.com/otn_software/asmlib/oracleasmlib-2.0.4-1.el5.x86_64.rpm
Retrieving http://download.oracle.com/otn_software/asmlib/oracleasmlib-2.0.4-1.el5.x86_64.rpm
warning: /var/tmp/rpm-tmp.ZhUEGs: Header V3 DSA/SHA1 Signature, key ID 1e5e0159: NOKEY
Preparing... ########################################### [100%]
1:oracleasmlib ########################################### [100%]

[root@generic ~]# oracleasm-discover
Using ASMLib from /opt/oracle/extapi/64/asm/orcl/1/libasm.so
[ASM Library - Generic Linux, version 2.0.4 (KABI_V2)]
Discovered disk: ORCL:DATA1 [192717 blocks (98671104 bytes), maxio 512]
Discovered disk: ORCL:DATA2 [1012032 blocks (518160384 bytes), maxio 512]

Now back to the title of this post. Oracleasmlib is not necessary to have in order to use ASM. It only offers the management of the disk devices to make them accessible to ASM without a lot of manual intervention. If you would like to understand the philosophical differences between using oracleasmlib or not, there is plenty of debate over at the Oracle Forums.

Very simply, the only thing ASM needs to consider a candidate ASM disk is a block device with the appropriate ownership and permissions. A simple test is to directly change the ownership and permissions of the block devices you have created for ASM and use asmca with a different discovery path that will find them.

[root@generic ~]# service oracleasm stop
Dropping Oracle ASMLib disks: [ OK ]
Shutting down the Oracle ASMLib driver: [ OK ]

[root@generic ~]# rpm -ev oracleasmlib

[root@generic ~]# rpm -ev oracleasm-support
warning: /etc/sysconfig/oracleasm saved as /etc/sysconfig/oracleasm.rpmsave

[root@generic ~]# chown grid.dba /dev/{sdb1,sdc1}

[root@generic ~]# chmod 0660 /dev/{sdb1,sdc1}

[root@generic ~]# ll /dev/{sdb1,sdc1}
brw-rw---- 1 grid dba 8, 17 Nov 2 06:53 /dev/sdb1
brw-rw---- 1 grid dba 8, 33 Nov 2 06:55 /dev/sdc1

That was a lot of work, especially if you are adding more devices and it won’t survive a reboot. Fortunately, there is a supported method to do this with more automation (and more importantly to survive a reboot) using a native Linux tool called “udev”. udev already does what we just did with all of the other devices present in /dev. We just need to tell it what specifically to do by creating a configuration file.

[root@generic ~]# DEVS=(sdb sdc)
NUM=$( sed -r -n -e '$!d' -e 's/.*NAME="asm-disk([^"]+)".*/\1/p' /etc/udev/rules.d/99-oracle-asmdevices.rules 2>/dev/null )
NUM=${NUM:-0}
for I in ${DEVS[*]}; do
  ((NUM++))
  echo 'KERNEL=="sd?1", BUS=="scsi", PROGRAM=="/sbin/scsi_id -g -u -d /dev/$parent", RESULT=="'\
  "$( /sbin/scsi_id -g -u -d /dev/$I )\", NAME=\"asm-disk$NUM"\
  '", OWNER="grid", GROUP="dba", MODE="0660"'\
  >> /etc/udev/rules.d/99-oracle-asmdevices.rules
done

[root@generic ~]# cat /etc/udev/rules.d/99-oracle-asmdevices.rules
KERNEL=="sd?1", BUS=="scsi", PROGRAM=="/sbin/scsi_id -g -u -d /dev/$parent", RESULT=="1ATA_VBOX_HARDDISK_VBa70ffc27-81275aac", NAME="asm-disk1", OWNER="grid", GROUP="dba", MODE="0660"
KERNEL=="sd?1", BUS=="scsi", PROGRAM=="/sbin/scsi_id -g -u -d /dev/$parent", RESULT=="1ATA_VBOX_HARDDISK_VB3a0c6747-92f57443", NAME="asm-disk2", OWNER="grid", GROUP="dba", MODE="0660"

[root@generic ~]# udevadm test /block/sdb/sdb1
udev_rules_apply_to_event: OWNER 54322 /etc/udev/rules.d/99-oracle-asmdevices.rules:2
udev_rules_apply_to_event: GROUP 54322 /etc/udev/rules.d/99-oracle-asmdevices.rules:2
udev_rules_apply_to_event: MODE 0660 /etc/udev/rules.d/99-oracle-asmdevices.rules:2
udev_rules_apply_to_event: NAME 'asm-disk1' /etc/udev/rules.d/99-oracle-asmdevices.rules:2
udev_rules_apply_to_event: PROGRAM '/sbin/scsi_id -g -u -d /dev/sdb' /etc/udev/rules.d/99-oracle-asmdevices.rules:3
util_run_program: '/sbin/scsi_id -g -u -d /dev/sdb' started
util_run_program: '/sbin/scsi_id' (stdout) '1ATA_VBOX_HARDDISK_VBa70ffc27-81275aac'
util_run_program: '/sbin/scsi_id -g -u -d /dev/sdb' returned with exitcode 0
udev_node_add: creating device node '/dev/asm-disk1', devnum=8:17, mode=0660, uid=54322, gid=54322
udev_node_mknod: mknod(/dev/asm-disk1, 060660, (8,17))
udev_node_mknod: set permissions /dev/asm-disk1, 060660, uid=54322, gid=54322
node_symlink: atomically replace '/dev/block/8:17'


[root@generic ~]# udevadm control --reload-rules

[root@generic ~]# udevadm control --start-exec-queue

[root@generic ~]# partprobe /dev/sdb1

[root@generic ~]# partprobe /dev/sdc1

[root@generic ~]# ll /dev/asm*
brw-rw---- 1 grid dba 8, 17 Nov  2 06:33 /dev/asm-disk1
brw-rw---- 1 grid dba 8, 33 Nov  2 06:33 /dev/asm-disk2

Finally, here is a good overview of the current state of Oracle ASMlib from Wim Coekaerts, the Senior Vice President of Linux and Virtualization Engineering at Oracle.

  • Oracle ASM does not in any way require ASMLib to function completely. ASMlib is a small set of extensions, in particular to make device management easier but there are no extra features exposed through Oracle ASM with ASMLib enabled or disabled. Often customers confuse ASMlib with ASM. again, ASM exists on every Oracle supported OS and on every supported Linux OS, SLES, RHEL, OL without ASMLib
  • Oracle ASMLib userspace is available for OTN and the kernel module is shipped along with OL/UEK for every build and by SuSE for SLES for every of their builds
  • ASMLib kernel module was built by us for RHEL4 and RHEL5 but we do not build it for RHEL6, nor for the OL6 RHCK kernel. Only for UEK
  • ASMLib for Linux is/was a reference implementation for any third party vendor to be able to offer, if they want to, their own version for their own OS or storage
  • ASMLib as provided by Oracle for Linux continues to be enhanced and evolve and for the kernel module we use UEK as the base OS kernel

References:

http://public-yum.oracle.com
http://www.oracle.com/technetwork/server-storage/linux/asmlib/index-101839.html
http://www.oracle.com/technetwork/server-storage/linux/uln-095759.html
https://support.oracle.com/epmos/faces/DocumentDisplay?id=1444115.1
http://oracle-base.com/articles/linux/udev-scsi-rules-configuration-in-oracle-linux-5-and-6.php
http://fritshoogland.wordpress.com/2012/07/23/using-udev-on-rhel-6-ol-6-to-change-disk-permissions-for-asm
https://blogs.oracle.com/wim/entry/asmlib

Discovering Systemd

I finally started playing with my Raspberry Pi (RP) after looking at it for a month still in the package. I looked at the available pre-built distros and immediately clicked on Arch Linux Arm. I have installed Arch Linux before on an older laptop that I have and was fascinated by it for no other reason than it was so different from the Red Hat type systems that I am so used to. If the terms pacman or rc.conf aren’t familiar to you, give Arch Linux a try and see what you think.

Instead of seeing the familiar boot process of Arch Linux when I powered up the RP, I got a sub-10 second boot with a few messages appearing after the login prompt is already on the screen. Granted, I am booting from an SD card but considering the entire compute power consists of 512MB of RAM (total being shared with the GPU) and a 700MHz processor, that is crazypants fast.

I started exploring the file system and hit one dead end after another looking for familiar files. /etc/inittab, /etc/rc.conf, chkconfig, etc. couldn’t be found. I turned to the documentation. Sure enough, SysVInit had been replaced with Systemd. I had to reset everything I knew about the Linux boot process and learn from scratch which brings me to now. I understand the basic layout and how to query systemd but that’s about it. I’m looking for some good documentation to load onto my Kindle.

My official job title is Oracle DBA but my roots lie in Linux administration. Many of my servers run Oracle Linux which is ostensibly a port of Red Hat Linux. The Wikipedia page for systemd says that RHEL 7 will at least support systemd. Despite the myriad forum posts of neophytes crying about how much more work it will be for sysadmins to support systemd, I see it as an approaching standard along with GPT replacing MBR. I want to learn about this fascinating technology and be on the leading edge of it when it hits mainstream. Next step, talk to the Oracle Linux SE’s and find out where and when.