Thursday 18 April 2013

Solaris 10 - Service Management Facility

Most of the time i work on solaris machines and need to maintain services on these machines. But there are other users who uses these machines and by mistake they restart the services as root user. I've been thinking for a while on how to avoid this and also better way to manage services as it is tiresome job when you have to restart 50+ services manually by cdĂ­ng to the directory and run the startup script . Of course there are many auotmation tools in market and one i most like is puppet. But in this case i am not using puppet are any other third party automation tools but the solaris native SMF. In this post i've used the basic features of SMF.

To migrate the service to SMF, manifest file and method has to be created. The Manifest file is an xml and it's the key file where all the dependencies, method to be executed are defined.
Existing start procedure
1. cd /usr/local/test-service/
2. ls -ltr /usr/local/test-service/
-rwxr-xr-x   1 user1    group1    3646 Apr 18 06:25 user1agentctl
drwxr-xr-x   2 user1      group1     512 Apr 18 10:31 jars
-rw-r--r--   1 user1      group1          6 Apr 18 10:32 user1agent.pid
3. sux user1
4. ./user1agentctl -v start
5. Check if the process has started
[user1@test] $ cat user1agent.pid
22065
[user1@sjc3-vg1-java1] $ /usr/bin/ps -ef |grep 22065
user1    74 24627   0 10:36:54 pts/4       0:00 grep 22065
user1 22065     1   0 10:32:40 ?           0:01 javaXXXX -Xms256m -Xmx512m -Dapp.name=user1Processor

I need to do this 5 steps for every 50+ services, if the database goes down or the server crashed for some unkown reason. Using SMF simplified this work

Migrating service to SMF
Create the manifest file

[root@test] $ cat /var/svc/manifest/application/user1agent.xml


user1agent">
user1agent" type="service" version="1">
<create_default_instance enabled="false">

localhost/usr/local/test-service/user1agentctl"/>

svc/method/user1agent start" timeout_seconds="60">
<method_context>
<method_credential user="user1">

svc/method/user1agent stop" timeout_seconds="60">
<method_context>
<method_credential user="user1">


Create the method
[root@test] $ cat /lib/svc/method/user1agent
#!/sbin/sh
#
. /lib/svc/share/smf_include.sh
case "$1" in
start)
/usr/local/test-service/user1agentctl start
if [ $? -ne 0 ]
then
exit $SMF_EXIT_ERR_CONIG
fi
;;
stop)
/usr/local/test-service/user1agentctl stop
;;
*)
echo "Usage: $0 \c" >&2
echo "(start|stop)" >&2
exit 1
;;
esac
exit $SMF_EXIT_OK

Validate and import the manifest
[root@test] $ /usr/sbin/svccfg validate /var/svc/manifest/application/user1agent.xml
[root@test] $ /usr/sbin/svcadm restart manifest-import

Check if the service is added to the SMF
[root@test1] $ svcs -a |grep user1
disabled         10:32:24 svc:/application/user1agent:default

Let's do some testing

Enable the service SMF
/usr/sbin/svcadm enable svc:/application/user1agent:default
[root@test] $ svcs -a |grep user1
online         11:14:11 svc:/application/user1agent:default
root@test] $ /usr/bin/ps -ef |grep user1
user1 10600     1   1 11:14:12 ?           0:03 javaXXXX -Xms256m -Xmx512m -Dapp.name=user1Processor -classpath .::/usr/local/

Though i've enabled the service in SMF as root user, the process is running as user1. This is what i expected.

One more excellent feature is mentioned below

I will kill the process abruptly
[root@test] $ kill -9 10600                                                                                                                                           
[root@test] $ /usr/bin/ps -ef |grep user1
user1 18844     1   0 11:18:37 ?           0:06 javaXXXX -Xms256m -Xmx512m -Dapp.name=user1Processor -classpath .::/usr/local/jav

Even though i killed the process, the SMF has started it again.

These are other lot of features available in SMF, which i haven't explored yet.

Reference: http://bit.ly/13nE0Dw

Monday 4 March 2013

rpm error: Failed dependencies: rpmlib(FileDigests) <=4.6.0-1 ,rpmlib(PayloadIsXz) <= 5.2-1

I created a package called testpackage-SVNTRRev94-0044.el6.x86_64.rpm in my build machine and installed in my build machine to test it
[root@testsys1 x86_64]# rpm -ivh testpackage-SVNTRRev94-0044.el6.x86_64.rpm
  Preparing... ########################################### [100%]
  1:testpackage ########################################### [100%]

The installation went fine and the required files were placed in the appropriate directory as mentioned in the SPEC file.

Now i need to install the same package in the QA machine for the team to validate it,  but i couldn't install the package due to the below error,
[root@qasys1 x86_64]# rpm -ivh testpackage-SVNTRRev94-0044.el6.x86_64.rpm
error: Failed dependencies:
rpmlib(FileDigests) <= 4.6.0-1 is needed by testpackage-SVNTRRev94-0044.el6.x86_64.rpm
rpmlib(PayloadIsXz) <= 5.2-1 is needed by testpackage-SVNTRRev94-0044.el6.x86_64.rpm

Then did some google search and identified that my package was built using higher version of rpm and i tried installing it in machine which has lower version of rpm.
[root@testsys1 x86_64]# rpm --version
RPM version 4.8.0
[root@qasys1 x86_64]# rpm --version
RPM version 4.4.2.3

The features available in the higher version weren't available in the lowest version,
[root@testsys1 x86_64]# rpm --showrc
Features supported by rpmlib:
  rpmlib(BuiltinLuaScripts) = 4.2.2-1
  rpmlib(CompressedFileNames) = 3.0.4-1
  rpmlib(ConcurrentAccess) = 4.1-1
  rpmlib(ExplicitPackageProvide) = 4.0-1
  rpmlib(FileCaps) = 4.6.1-1
 rpmlib(FileDigests) = 4.6.0-1
  rpmlib(HeaderLoadSortsTags) = 4.0.1-1
  rpmlib(PartialHardlinkSets) = 4.0.4-1
  rpmlib(PayloadFilesHavePrefix) = 4.0-1
  rpmlib(PayloadIsBzip2) = 3.0.5-1
  rpmlib(PayloadIsLzma) = 4.4.2-1
  rpmlib(PayloadIsXz) = 5.2-1
  rpmlib(ScriptletInterpreterArgs) = 4.0.3-1
  rpmlib(VersionedDependencies) = 3.0.3-1
[root@qasys1 x86_64]# rpm --showrc
Features supported by rpmlib:
  rpmlib(VersionedDependencies) = 3.0.3-1
  PreReq:, Provides:, and Obsoletes: dependencies support versions.
  rpmlib(CompressedFileNames) = 3.0.4-1
  file name(s) stored as (dirName,baseName,dirIndex) tuple, not as path.
  rpmlib(PayloadIsBzip2) = 3.0.5-1
  package payload can be compressed using bzip2.
  rpmlib(PayloadFilesHavePrefix) = 4.0-1
  package payload file(s) have "./" prefix.
  rpmlib(ExplicitPackageProvide) = 4.0-1
  package name-version-release is not implicitly provided.
  rpmlib(HeaderLoadSortsTags) = 4.0.1-1
  header tags are always sorted after being loaded.
  rpmlib(ScriptletInterpreterArgs) = 4.0.3-1
  the scriptlet interpreter can use arguments from header.
  rpmlib(PartialHardlinkSets) = 4.0.4-1
  a hardlink file set may be installed without being complete.
  rpmlib(ConcurrentAccess) = 4.1-1
  package scriptlets may access the rpm database while installing.
  rpmlib(BuiltinLuaScripts) = 4.2.2-1
  internal support for lua scripts.

Now i could see the reason for the dependency failure ,  features rpmlib(FileDigests) ,rpmlib(PayloadIsXz) aren't available in the lower version of rpm and that's the reason for the failure of the installation of rpm. I decided to build my package without this features so that it can install in my QA machine without upgrading the rpm or installing the dependencies. I know this is not the right approach  as these features might provide a useful functionality  and i didn't explore what those are. But in my case the package just places files in certain directory structure with right permission bits, so i decided to disable these features and build the package.

[root@testsys1 x86_64]# rpmbuild -bb --define "_binary_filedigest_algorithm  1"  --define "_binary_payload 1" testpackage.spec

Then i installed the package in the QA machine without dependency issue,
[root@qasys1 x86_64]# rpm -ivh testpackage-SVNTRRev94-0044.el6.x86_64.rpm
 Preparing... ########################################### [100%]
  1:testpackage ########################################### [100%]

Reference : http://bit.ly/VZR5gW

Thursday 28 February 2013

patchadd -p lists the uninstalled patch

Hi,

Today i had this weird problem while installing a patch in Solaris 10.

I tried to install a patch called  100000-91 , but  it throwed me an error stating the higher version of the patch is installed. Below is the trace.
[root@madhu] $ cd /tmp/100000-91/
[root@madhu] $ /usr/sbin/patchadd .
Validating patches...
Loading patches installed on the system...
Done!
Loading patches requested to install.
Done!
Checking patches that you specified for installation.
Done!
Approved patches will be installed in this order:
100000-91
Checking installed patches...
A later version of 100000 has already been installed
Patchadd is terminating.

I executed the below command to list the patches installed in the system
[root@madhu] $ showrev -p
Patch: 100000-78
Patch: 100000-88
Patch: 100000-90

This looks fine as 100000-90 is not higher that 100000-91, then i know there is another command to list the patches installed in the system.
[root@madhu] $ /usr/sbin/patchadd -p
Patch: 100000-78
Patch: 100000-88
Patch: 100000-90
Patch: 100000-225

There is a difference between both these commands , now i can see 100000-225 patch is listed as installed. I will go-ahead and remove it.
[root@madhu] $ /usr/sbin/patchrm 100000-225
Validating patches...
Loading patches installed on the system...
Done!
Patch 100000-225 does not exist.

This is weird , the "patchadd -p" lists the 100000-225 as installed, but the patchrm says it does not exists. The patchadd and showrev fetches this information from the pkginfo file located in the subdirectories/var/sadm/pkg . I found the appropriate subdirectory for this patch and found it had the below entry in it.
PATCH_INFO_100000-225=backed out

Ok, this means the pkginfo says it's uninstalled, but why does patchadd lists it and showrev doesn't . Then i noted there was a hidden directory ".save.madhupatch" inside /var/sadm/pkg  and noted it's pkginfo file had the below entry.
PATCH_INFO_100000-225=Installed: Thu Aug 23 10:17:53 GMT 2012

Now i can understand that , patchadd refers this file instead of the other pkginfo which has the right information. I removed ".save.madhupatch" from /var/sadm/pkg . Then i was able to install  100000-91 patch in the system.

Note : I didn't figure out how and why this hidden directory exists and why the output of showrev and patchadd is different. Those areas are yet to explore.

Reference : http://bit.ly/XEXZZo