Skip to content

Commit

Permalink
Improving scriptlet related rpm plugin hooks.
Browse files Browse the repository at this point in the history
Three new hooks added:
PLUGINHOOK_SCRIPTLET_PRE_FUNC
Called before scriptlet execution
PLUGINHOOK_SCRIPTLET_FORK_POST_FUNC
Called after fork() but before scriptlet execution
PLUGINHOOK_SCRIPTLET_POST_FUNC
Called after scriptlet execution

Currently pre and post hooks are called for externals and internal lua scripts.
post hook is called even if scriptlet execution has failed and
the return code is given as an argument.

fork_post hook is only called for external scriptlets,
because for internal scriptlets no fork() is currently performed.

Signed-off-by: Panu Matilainen <[email protected]>
  • Loading branch information
ereshetova authored and pmatilai committed Nov 29, 2012
1 parent 9b995a7 commit e86bae3
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 23 deletions.
42 changes: 38 additions & 4 deletions lib/rpmplugins.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,17 +264,51 @@ rpmRC rpmpluginsCallPsmPost(rpmPlugins plugins, rpmte te)
return rc;
}

rpmRC rpmpluginsCallScriptSetup(rpmPlugins plugins, char* path)
rpmRC rpmpluginsCallScriptletPre(rpmPlugins plugins, const char *s_name, int type)
{
rpmRC (*hookFunc)(char*);
rpmRC (*hookFunc)(const char*, int);
int i;
rpmRC rc = RPMRC_OK;
const char *name = NULL;

for (i = 0; i < plugins->count; i++) {
name = plugins->names[i];
RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_SCRIPT_SETUP);
if (hookFunc(path) == RPMRC_FAIL)
RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_SCRIPTLET_PRE);
if (hookFunc(s_name, type) == RPMRC_FAIL)
rc = RPMRC_FAIL;
}

return rc;
}

rpmRC rpmpluginsCallScriptletForkPost(rpmPlugins plugins, const char *path, int type)
{
rpmRC (*hookFunc)(const char*, int);
int i;
rpmRC rc = RPMRC_OK;
const char *name = NULL;

for (i = 0; i < plugins->count; i++) {
name = plugins->names[i];
RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_SCRIPTLET_FORK_POST);
if (hookFunc(path, type) == RPMRC_FAIL)
rc = RPMRC_FAIL;
}

return rc;
}

rpmRC rpmpluginsCallScriptletPost(rpmPlugins plugins, const char *s_name, int type, int res)
{
rpmRC (*hookFunc)(const char*, int, int);
int i;
rpmRC rc = RPMRC_OK;
const char *name = NULL;

for (i = 0; i < plugins->count; i++) {
name = plugins->names[i];
RPMPLUGINS_SET_HOOK_FUNC(PLUGINHOOK_SCRIPTLET_POST);
if (hookFunc(s_name, type, res) == RPMRC_FAIL)
rc = RPMRC_FAIL;
}

Expand Down
43 changes: 37 additions & 6 deletions lib/rpmplugins.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ extern "C" {

#define PLUGINHOOK_PSM_PRE_FUNC pluginhook_psm_pre
#define PLUGINHOOK_PSM_POST_FUNC pluginhook_psm_post

#define PLUGINHOOK_SCRIPT_SETUP_FUNC pluginhook_script_setup

#define PLUGINHOOK_SCRIPTLET_PRE_FUNC pluginhook_scriptlet_pre
#define PLUGINHOOK_SCRIPTLET_FORK_POST_FUNC pluginhook_scriptlet_fork_post
#define PLUGINHOOK_SCRIPTLET_POST_FUNC pluginhook_scriptlet_post

enum rpmPluginHook_e {
PLUGINHOOK_NONE = 0,
Expand All @@ -37,9 +39,18 @@ enum rpmPluginHook_e {
PLUGINHOOK_TSM_POST = 1 << 7,
PLUGINHOOK_PSM_PRE = 1 << 8,
PLUGINHOOK_PSM_POST = 1 << 9,
PLUGINHOOK_SCRIPT_SETUP = 1 << 10
PLUGINHOOK_SCRIPTLET_PRE = 1 << 10,
PLUGINHOOK_SCRIPTLET_FORK_POST = 1 << 11,
PLUGINHOOK_SCRIPTLET_POST = 1 << 12
};

/* indicates the way the scriptlet is executed */
typedef enum rpmScriptletExecutionFlow_e {
RPMSCRIPTLET_NONE = 0,
RPMSCRIPTLET_FORK = 1 << 0,
RPMSCRIPTLET_EXEC = 1 << 1
} rpmScriptletExecutionFlow;

typedef rpmFlags rpmPluginHook;

/** \ingroup rpmplugins
Expand Down Expand Up @@ -167,12 +178,32 @@ rpmRC rpmpluginsCallPsmPre(rpmPlugins plugins, rpmte te);
rpmRC rpmpluginsCallPsmPost(rpmPlugins plugins, rpmte te);

/** \ingroup rpmplugins
* Call the script setup plugin hook
* Call the pre scriptlet execution plugin hook
* @param plugins plugins structure
* @param s_name scriptlet name
* @param type indicates the scriptlet execution flow, see rpmScriptletExecutionFlow
* @return RPMRC_OK on success, RPMRC_FAIL otherwise
*/
rpmRC rpmpluginsCallScriptletPre(rpmPlugins plugins, const char *s_name, int type);

/** \ingroup rpmplugins
* Call the post fork scriptlet plugin hook.
* @param plugins plugins structure
* @param path scriptlet path
* @param type indicates the scriptlet execution flow, see rpmScriptletExecutionFlow
* @return RPMRC_OK on success, RPMRC_FAIL otherwise
*/
rpmRC rpmpluginsCallScriptletForkPost(rpmPlugins plugins, const char *path, int type);

/** \ingroup rpmplugins
* Call the post scriptlet execution plugin hook
* @param plugins plugins structure
* @param path script path
* @param s_name scriptlet name
* @param type indicates the scriptlet execution flow, see rpmScriptletExecutionFlow
* @param res scriptlet execution result code
* @return RPMRC_OK on success, RPMRC_FAIL otherwise
*/
rpmRC rpmpluginsCallScriptSetup(rpmPlugins plugins, char* path);
rpmRC rpmpluginsCallScriptletPost(rpmPlugins plugins, const char *s_name, int type, int res);

#ifdef __cplusplus
}
Expand Down
38 changes: 27 additions & 11 deletions lib/rpmscript.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ struct rpmScript_s {
/**
* Run internal Lua script.
*/
static rpmRC runLuaScript(int selinux, ARGV_const_t prefixes,
static rpmRC runLuaScript(rpmPlugins plugins, int selinux, ARGV_const_t prefixes,
const char *sname, rpmlogLvl lvl, FD_t scriptFd,
ARGV_t * argvp, const char *script, int arg1, int arg2)
{
Expand Down Expand Up @@ -93,7 +93,7 @@ static rpmRC runLuaScript(int selinux, ARGV_const_t prefixes,

static const char * const SCRIPT_PATH = "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin";

static void doScriptExec(rpmPlugins plugins, int selinux, ARGV_const_t argv, ARGV_const_t prefixes,
static void doScriptExec(int selinux, ARGV_const_t argv, ARGV_const_t prefixes,
FD_t scriptFd, FD_t out)
{
int pipes[2];
Expand Down Expand Up @@ -171,10 +171,7 @@ static void doScriptExec(rpmPlugins plugins, int selinux, ARGV_const_t argv, ARG
}

if (xx == 0) {
/* Run script setup hook for all plugins */
if (rpmpluginsCallScriptSetup(plugins, argv[0]) != RPMRC_FAIL) {
xx = execv(argv[0], argv);
}
xx = execv(argv[0], argv);
}
}
_exit(127); /* exit 127 for compatibility with bash(1) */
Expand Down Expand Up @@ -263,7 +260,13 @@ static rpmRC runExtScript(rpmPlugins plugins, int selinux, ARGV_const_t prefixes
} else if (pid == 0) {/* Child */
rpmlog(RPMLOG_DEBUG, "%s: execv(%s) pid %d\n",
sname, *argvp[0], (unsigned)getpid());
doScriptExec(plugins, selinux, *argvp, prefixes, scriptFd, out);

/* Run scriptlet post fork hook for all plugins */
if (rpmpluginsCallScriptletForkPost(plugins, *argvp[0], RPMSCRIPTLET_FORK | RPMSCRIPTLET_EXEC) != RPMRC_FAIL) {
doScriptExec(selinux, *argvp, prefixes, scriptFd, out);
} else {
_exit(126); /* exit 126 for compatibility with bash(1) */
}
}

do {
Expand Down Expand Up @@ -307,6 +310,7 @@ rpmRC rpmScriptRun(rpmScript script, int arg1, int arg2, FD_t scriptFd,
ARGV_t args = NULL;
rpmlogLvl lvl = warn_only ? RPMLOG_WARNING : RPMLOG_ERR;
rpmRC rc;
int script_type = RPMSCRIPTLET_FORK | RPMSCRIPTLET_EXEC;

if (script == NULL) return RPMRC_OK;

Expand All @@ -316,12 +320,24 @@ rpmRC rpmScriptRun(rpmScript script, int arg1, int arg2, FD_t scriptFd,
} else {
argvAdd(&args, "/bin/sh");
}

if (rstreq(args[0], "<lua>"))
script_type = RPMSCRIPTLET_NONE;

if (rstreq(args[0], "<lua>")) {
rc = runLuaScript(selinux, prefixes, script->descr, lvl, scriptFd, &args, script->body, arg1, arg2);
} else {
rc = runExtScript(plugins, selinux, prefixes, script->descr, lvl, scriptFd, &args, script->body, arg1, arg2);
/* Run scriptlet pre hook for all plugins */
rc = rpmpluginsCallScriptletPre(plugins, script->descr, script_type);

if (rc != RPMRC_FAIL) {
if (script_type & RPMSCRIPTLET_EXEC) {
rc = runExtScript(plugins, selinux, prefixes, script->descr, lvl, scriptFd, &args, script->body, arg1, arg2);
} else {
rc = runLuaScript(plugins, selinux, prefixes, script->descr, lvl, scriptFd, &args, script->body, arg1, arg2);
}
}

/* Run scriptlet post hook for all plugins */
rpmpluginsCallScriptletPost(plugins, script->descr, script_type, rc);

argvFree(args);

return rc;
Expand Down
6 changes: 4 additions & 2 deletions plugins/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,7 @@ rpmRC PLUGINHOOK_TSM_POST_FUNC(rpmts ts);
rpmRC PLUGINHOOK_PSM_PRE_FUNC(rpmte te);
rpmRC PLUGINHOOK_PSM_POST_FUNC(rpmte te);

/*per script plugin hooks */
rpmRC PLUGINHOOK_SCRIPT_SETUP_FUNC(char* path);
/*per scriptlet plugin hooks */
rpmRC PLUGINHOOK_SCRIPTLET_PRE_FUNC(const char *s_name, int type);
rpmRC PLUGINHOOK_SCRIPTLET_FORK_POST_FUNC(const char *path, int type);
rpmRC PLUGINHOOK_SCRIPTLET_POST_FUNC(const char *s_name, int type, int res);

0 comments on commit e86bae3

Please sign in to comment.