使用libscf.so实现SMF服务refresh方法( 三 )


int read_config(void)
{
memset(filename, 0, sizeof(filename));
/* connect to the current SMF global repository */
handle = scf_handle_create(SCF_VERSION);
/* allocate scf resources */
sc = scf_scope_create(handle);
svc = scf_service_create(handle);
pg = scf_pg_create(handle);
prop = scf_property_create(handle);
value = https://www.rkxy.com.cn/dnjc/scf_value_create(handle);
/* if failed to allocate resources, exit */
if (handle == NULL || sc == NULL || svc == NULL ||
pg == NULL || prop == NULL || value =https://www.rkxy.com.cn/dnjc/= NULL)
{
destroy_scf();
return CONFIG_ERROR;
}
/* bind scf handle to the running svc.configd daemon */
if ((scf_handle_bind(handle)) == -1)
{
destroy_scf();
return CONFIG_ERROR;
}
/* get the scope of the localhost in the current repository */
if (scf_handle_get_scope(handle, SCF_SCOPE_LOCAL, sc) == -1)
{
destroy_scf();
return CONFIG_ERROR;
}
/* get the service of "application/myapp" within the scope */
if (scf_scope_get_service(sc, "application/myapp", svc) == -1)
{
destroy_scf();
return CONFIG_ERROR;
}
/* get the property group of "myapp" within the given service */
if (scf_service_get_pg(svc, "myapp", pg) == -1)
{
destroy_scf();
return CONFIG_ERROR;
}
/* get the propery of "log_filename" within the given property group */
if (scf_pg_get_property(pg, "log_filename", prop) == -1)
{
destroy_scf();
return CONFIG_ERROR;
}
/* get the value of the given property */
if (scf_property_get_value(prop, value) == -1)
{
destroy_scf();
return CONFIG_ERROR;
}
/* retrIEve the value as a string */
if (scf_value_get_astring(value, filename, sizeof(filename)) == -1)
{
destroy_scf();
return CONFIG_ERROR;
}
/* free all resources */
destroy_scf();
return RUN_OK; /* OK */
}
/* free all allocated scf resources */
void destroy_scf(void)
{
if (value != NULL) scf_value_destroy(value);
if (prop != NULL) scf_property_destroy(prop);
if (pg != NULL) scf_pg_destroy(pg);
if (svc != NULL) scf_service_destroy(svc);
if (sc != NULL) scf_scope_destroy(sc);
if (handle != NULL) scf_handle_destroy(handle);
}
/* initialize application */
int app_init(void)
{
/* setup the SIGUSR1 signal handler */
signal(SIGUSR1, sig_usr);
return RUN_OK; /* OK */
}
/* signal handler for SIGUSR1 */
void sig_usr(int signo)
{
/* re-read the configuration when signal is received */
if (read_config() != RUN_OK) exit(CONFIG_ERROR);
}
在myapp.c程序中,read_config()就是读取保存在SMF全局资源库配置的过程 。除了在main()过程第43行服务启动时被调用外,还在sig_usr()过程中第206行被调用 。而sig_usr()过程在app_init()初始化过程中被设定为SIGUSR1信号的处理程序 。这意味着,此服务在运行过程中只要收到SIGUSR1信号后,就会重新读取存在SMF资源库中的配置信息 。
使用libscf.so的API读取SMF全局资源库/etc/svc/repository.db服务配置属性的一般流程如下图所示 。
本例中,服务名字为application/myapp 。属性组myapp内只有一个属性log_filename,它指定了日志文件的全路径文件名 。由于此属性为字符型,所以使用scf_value_get_astring()将属性值value转换字符串置于filename 。如果服务有更多的属性,可以多次执行循环1,甚至如果用户服务有多个属性组,可以多次执行循环2,直至将所有属性全部读出 。
read_config()过程的第114至118行逻辑是申请scf资源,其目的是先得到保存相关scf资源的内存 。相应的destroy_scf()过程是释放scf资源 。当配置读取完毕后,应将所有申请的scf资源释放 。

推荐阅读