SMF功能概览
Solaris 10中的SMF提供了强大的服务管理功能。以下是一部分重要的功能:
1. SMF向系统管理员提供统一的服务管理平台,利用svcs(1)命令就可以查看SMF所辖的各种服务,利用svccfg(1M)和svcadm(1M)命令可以配置各种服务和管理各种服务。对于传统UNIX,系统管理员必须记住各种服务不同的启动/停止方法、配置修改方法、服务状态及日志查询方法而言, SMF统一管理平台极大地降低了系统管理的难度,也降低了系统管理出错的机率。
2. SMF提供各服务间的依赖关系设定,可以自动按依赖关系顺序启动各服务。这对于传统UNIX以rc脚本文件名排列先后决定启动/停止顺序而言,SMF提供了无可比拟的完善的管理能力。
3. 并行启动不相互依赖的服务,从而使系统启动更快。由于各服务的依赖关系在SMF中有明确的定义,所以不相干的服务完全可以并行启动而不必担心冲突。
4. 自动侦测所辖服务的运行状态,在必要时可以重启服务或停止服务。作为预测性自愈技术(Predictive Self-Healing)的组成部分,SMF可以对所辖服务进行状态监控。根据服务的需要,SMF可以在服务进程不存在时,自动重启服务,或者在服务所依赖关系发生问题时,重启服务。也可以在服务连续发生问题时,将服务置为维护(maintenance)状态。
当然,SMF的管理机制并不排斥传统rc脚本运行服务的机制,以最大程度兼容传统方式的运作。有关SMF更多的介绍,请参看Solaris Service Management Facility - Quickstart Guide。
一个简单的服务程序
<表1是一个简单的程序myapp.c,它运行后将成为后台守护进程存在于系统中,并每间隔5秒钟向日志文件/tmp/myapp.log插入一行记录以报告自己的存在。虽然它实际上不向外提供任何服务,但该程序模拟了一般服务程序的设计结构和运行模式。即,程序运行后以守护进程形式存在于系统,程序头部有模拟服务配置read_config()和初始化app_init()逻辑,中部使用sleep(5)模拟等待服务请求逻辑,通过向日志插入记录模拟服务请求处理逻辑,然后返回至循环开始处sleep(5)继续等待下一个服务请求等。只要在此结构上修改和扩充相应的逻辑就可以将此程序修改为一个真正的服务程序。本文要点是说明如何部署应用为SMF服务,所以仅采用此程序作为例子。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
/***************************************/ /* myapp.c */ /***************************************/ #include <unistd.h> #include <sys/param.h> #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <stdlib.h> #include <time.h> /* global exit status code */ #define RUN_OK 0 #define CONFIG_ERROR 1 #define FATAL_ERROR 2 /* function declaration */ int read_config(void); int app_init(void); void daemonize(void); int main(int argc, char **argv) { FILE *fp; time_t t; /* Read the app configuration here if applicable. */ /* If error occurred, return non-zero. */ if (read_config() != RUN_OK) { printf("%s: read configuration failuren", argv[0]); exit(CONFIG_ERROR); } /* Initialize application. Any error, return non-zero. */ if (app_init() != RUN_OK) { printf("%s: initialization failuren", argv[0]); exit(FATAL_ERROR); } daemonize(); /* Make the application a daemon. */ /* Service logic is placed here. */ while (1) { sleep(5); /* Sleep for 5 seconds. In a real application, it could be */ /* waiting for service requests, e.g. waiting on message */ /* queue, etc. */ /* service logic */ if ((fp = fopen("/tmp/myapp.log","a")) != NULL) { t = time(0); fprintf(fp, "myapp is running at %sn",asctime(localtime(&t))); fclose(fp); } else { exit(FATAL_ERROR); } } } /* make the application a daemon */ void daemonize(void) { int pid; int i; if (pid = fork()) exit(RUN_OK); /* parent exits */ else if (pid < 0) exit(FATAL_ERROR); /* fork() failed */ /* first child process */ setsid(); if (pid = fork()) exit(RUN_OK); /* first child exits */ else if(pid < 0) exit(FATAL_ERROR); /* fork() failed */ /* second child */ for (i = 0; i < NOFILE; ++i) /* close all files */ close(i); chdir("/"); /* change directory to root(/) directory */ umask(0); /* set proper file mask */ } /* read configuration */ int read_config(void) { return RUN_OK; /* OK */ } /* initialize application */ int app_init(void) { return RUN_OK; /* OK */ } |
利用Sun公司最新推出的C/C++/Fortran开发及编译环境Sun Studio 11,使用以下命令将myapp.c编译成可执行程序myapp。
| $ /opt/SUNWspro/bin/cc -o ./myapp ./myapp.c |
或者直接使用Solaris 10自带的gcc编译器将myapp.c编译成可执行程序myapp。
| $ /usr/sfw/bin/gcc -o ./myapp ./myapp.c |
编译成功后在当前目录下会生成myapp可执行程序。本例假设当前目录为/export/home/smfdemo。直接在命令行输入. /myapp就可以启动myapp为后台守护进程,同时可以在/tmp目录下找到myapp.log文件。使用“/usr/bin/tail -f /tmp/myapp.log”命令可以看到进程myapp不断在日志文件中报告自己的存在。为了使这个进程在服务器启动时自动运行,传统做法一般需要写三个shell脚本。其中一个shell脚本置于/etc/init.d目录下用以实际启动和停止myapp服务(例如<表2所示的/etc/init.d/myapp.sh)。另外两个shell脚本的名字分别以S和K开头(例如,S79myapp和K79myapp),置于合适的/etc/rc?.d目录下(例如,/etc/rc2.d目录下),分别以不同参数(start和stop)调用 /etc/init.d/myapp.sh。操作系统在boot时会自动运行S开头的脚本以启动myapp服务,而在shutdown时自动运行K开头的脚本以关闭myapp服务。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#!/sbin/sh ############################################################################### # /etc/init.d/myapp.sh # ############################################################################### RUN_OK=0 CONFIG_ERROR=1 FATAL_ERROR=2 case "$1" in 'start') /export/home/smfdemo/myapp if [ $? -eq $CONFIG_ERROR ]; then exit $CONFIG_ERROR fi if [ $? -eq $FATAL_ERROR ]; then exit $FATAL_ERROR fi ;; 'stop') /usr/bin/pkill myapp ;; *) echo "Usage: $0 { start | stop }" ;; esac exit $RUN_OK |
SMF可部署的服务
本节讲述如何将上述例子改为SMF可部署的服务。根据SMF的要求,开发一个SMF可部署的服务需要至少以下几个步骤。
创建manifest文件
SMF manifest文件是一个XML文件,它用以定义SMF服务各属性。比如,定义服务名称、服务依赖关系、服务启动方法、服务停止方法、服务所需参数等。创建manifest文件最简单的方法是从/var/svc/manifest目录下挑选已存在的相同类型的服务XML文件,将它拷贝到开发目录,比如/export/home/smfdemo目录下,以拷贝件为基础修改而成。本文是个简单的服务,所以参考了 /var/svc/manifest/system/utmp.xml文件(因为它也很简单),在其基础上修改成表3所示的/export/home/smfdemo/myapp.xml。
评论加载中…


当前位置:





