As part of an Automated Environment Management initiative, recently, I had
to work with Solaris Service Management Facility (SMF) extensively. In
order to make the implementation right, I had to look several different
documentations, blogs, consult with colleagues, learn through error and
trial methods. The main intention of this blog is - kind of 'give back to
community', what I have learned.
Let's get started. Since, you are visiting this page, I assume, you are
already familiar with the SMF concept and looking to resolve specific
issue or digging some specific information in SMF domain. If you are new
to SMF, you can learn the basic of SMF from Oracle site
here.
Why SMF?
In Unix world, traditionally we used to
work with init script as a start-up mechanism. SMF may have been evolved
from legacy init, but it is much more flexible, robust, and very well
crafted. SMF helps to make environment management easier, uniform and
align with security practices as well.
In this posts, I'll explain SMF through a working
example. First, I have to warn you that some of the steps here
possibly overdone to show the concept in detail or underdone to minimize
the size of the blog.
Anyway, here is what we are going to do. We have
an environment as described below:
- Solaris 11 (64 bit VirtualBox guest VM running on 64 bit Windows 10
Host) and Oracle Directory Server 11g installed under
/opt/ods/dsee7
And as part of this learning process, I'll show you the following:
- Create no-login user 'dirservd', this user will own the Oracle
Directory Server (ODS) instances to be created.
- Create 'odsadm' user that will operate/manage SMF services for ODS
instances to be created.
- Create two Oracle Directory Server (ODS) instances 'odsInst1' and
'odsInst2', both listening on privileged ports (ports ranging from 1
to 1023)
- Define SMF service by customizing 'svcbundle' generated service
manifest file and adding required method credential privileges for
'dirservd' user and required SMF service management authorization for
'odsadm' user.
- Define script file to be invoked by service method execution.
- Show how to add and assign authorization.
- Import service artifacts to create SMF service for ODS instances.
As we go through, I'll also highlight little bit on following topics:
- Using product specific tool to create service vs. using standard SMF
tool - any benefit? - provide specific example for ODS.
- Generating SMF manifest file vs re-using available template and
modifying for particular use.
- Solaris 10 vs Solaris 11 from SMF perspective - few notes related to
examples.
- Parameterizing the SMF manifest file.
- Debugging SMF service.
Create user accounts and groups to be used
- Group 'dirservd' and user 'dirservd' will be created and for
security reason, user account 'dirservd' will be converted to
'no-login'. 'dirservd' will be a daemon/application user.
- User 'odsadm' will be created as a member of default group 'staff'.
'odsadm' will be service operator/administrator's user account.
Note: If you like to know more about 'no-login' account, I suggest you to
look Glenn Brunnet's blog, "
Managing Non-Login and Locked Solaris Accounts"
Create Oracle Directory Server (ODS) Instances
As stated above, for this scenario, we will create two instances both
listening on privileged ports (ports ranging from 1 to 1023). As you know
by default only root user can start process listening on
privileged ports.
- 1st instance will listen on default ports: 389 (non-secure) and 636
(secure)
- 2nd instance will listen on: 489 (non-secure) and 736 (secure)
Notes:
- make sure above mentioned ports are not being used by another
processes. You can check using netstat command: netstat -na and grep
the above mentioned ports.
- Now, in order to create instance(s) that listen on privileged
ports, you need to execute 'dsadm' command as root user.
As seen above, two ODS instances have been created. Now, it's time to
create SMF service. You can actually use ODS command 'dsadm' to create SMF
service, but it's not flexible enough. When I say not flexible enough, I
mean this command does not give you following options:
- no option to customize service name,
- no option to specify service model like 'transient' or 'daemon' etc.
- no option to specify execution 'privileges' in the service
definition level
- no option to specify service management authorization in the service
definition level.
- you can't view the manifest file.
Here, anyway, I quickly show you how to use 'dsadm' command to create SMF
service, but we'll delete the service thus created and use generic SMF
tool to recreate.
We explored 'dsadm' tool little bit, now let's move forward and explore
generic SMF ways.
Create SMF Manifest file.
Service manifest file is one of the most important component of Service
Management Framework. It defines basic service information as well as
service dependencies, required privileges, and start, stop command
along with other required information. Now the question is how to put
together a SMF manifest file. There are few options here:
- Copy one of the service manifest files for other service and
customize it or create from scratch manually. You can find these files under /lib/svc/manifest or
/var/svc/manifest in your Solaris server.
- Generate one using 'svcbundle' and customize it.
If you go with option #1, there are a lot of documentations from Oracle or
others available on the web. I found Oracle White Paper '
How
to Create an Oracle® Solaris Service Management Facility Manifest'
very informative.
However, as part of this exercise, we look into option #2. We'll use
'svcbundle' to generate our minimal SMF manifest file and customize it for
our purpose. I found Glynn Foster's Oracle
Technet
article on using svcbundle very handy. However, the best way to learn how to use svcbundle is to run command with 'help'
option and play with it:
I also suggest you to look the XML schme file (service_bundle.dtd.1) that
dictates the structure of each SMF Manifest file. It is available under
'/usr/share/lib/xml/dtd/' in your Solaris box.
Here we will generate a simple SMF manifest file for a single ODS instance
and modify it for our multi-instances service environment:
Above, we are using '-o <outputfile>' option instead of '-i' install
option, so that we can modify the generated file before installing it. As
you can see, start-method, stop-method, and refresh-method, refers to custom script file '/lib/svc/method/manage_ods'. I'll show you how to put
together that file below. We have also defined two common application properties at service level
(service-property), which are common to both instances:
ODS_HOME
ODS_INSTANCES_HOME
And one property at instance level (instance-property), which can be
unique to each instance.
EXEC_OPTIONS
Note: It is just to show how instance specific parameter can be used. In
this example, we are assigning empty string for EXEC_OPTION
Here is the generated file:
Below is customized SMF Manifest file for our purpose. See the comments
within the file for more information.
In customized file above, added fragments of code is in
green
and modified fragment is in
blue.
Relevant comment has also been added so that it is easy to understand. As
you can see new instance definition for 'odsInst2' has also been added
along with privileges for 'dirservd' user and authorizations '
solaris.smf.manage.ods'
and
'
solaris.smf.value.ods
'
for service operator/administrator to administer the service. These two
authorization will be assigned to 'odsadm' user.
Create custom script file to be invoked by service executable methods
Below is script source for 'manage_ods' file. As shown, script
retrieves parameter values supplied from SMF manifest for the service and
instance and defines start, stop and refresh methods.
Pink colored lines in the script above show how parameters (as property
name and value) set in the SMF manifest file are retrieved here in the
script and utilized, making it usable from one environment to another
and one instances to multiple.
At this point we have everything we need in order to create SMF service.
Let's upload/stage our SMF manifest file 'ods.xml' and script file
'manage_ods' into Solaris server somewhere in the /tmp directory. Below
are some important steps, you need to carry out in order to create SMF
service successfully:
1) Validate the SMF Manifest file as shown below and make sure no
error.
2) [Optional ] Make sure there is no existing SMF service with the
same name. Below command queries the SMF service database. Here is an
example:
3) Copy files to target location
4) Add required authorization(s) defined in the SMF manifest file
into /etc/security/auth_attr
5) Assign authorizations to service operator/administrator account.
In our case we'll assign these authorizations to 'odsadm' user.
Note: Before modifying the authorization for a given account, you may want
to see what currently assigned values are and take a note just in case if
you need to backout.
Note: the usermod command basically adds/updates /etc/user_attr file. If
you are an advanced user, you may directly update /etc/user_attr file.
6) Register the service into SMF
7) Verify the service
Note: As you can see the currently service is in disabled state, it's
because in the manifest file we defined initial state to be
'enabled=false' If you need service to be started automatically on system reboot make sure to have 'enabled=true'.
8) Now let's start the service as 'odsadm' user and make sure it is
started
9) Troubleshooting (if any)
- Look the service log. You can find the location of service log by
running command 'svcs -l <service-name>'
- Use svcs debugging using 'svcs -xv' which gives all services that
are having issue(s) or 'svcs -xv <service-name>' for particular
service.
- A lot of time it could be privilege related. You can debug it using
'ppriv' command. See ppriv
details.
This concludes our SMF walkthrough. Hope, you find it useful. Now, you
go ahead and use SMF in your own environment. Happy SMFing!