Improving scriptlet related rpm plugin hooks.
authorElena Reshetova <elena.reshetova@intel.com>
Thu, 22 Nov 2012 18:49:27 +0000 (20:49 +0200)
committerAnas Nashif <anas.nashif@intel.com>
Sun, 3 Feb 2013 00:44:45 +0000 (16:44 -0800)
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 <pmatilai@redhat.com>
lib/rpmplugins.c
lib/rpmplugins.h
lib/rpmscript.c
plugins/plugin.h

index d533b708a5f37772e32fc5dcc83ef3c1b68d3bae..c721cadbcaa5c788563bbb0ec60d1fc28e123b34 100644 (file)
@@ -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;
     }
 
index 153b8a99b88ee416ef0e493f78019f11634c4251..ffb8fe1619d0fe0a54befd3abad57b4f1cea3fef 100644 (file)
@@ -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,
@@ -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
@@ -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
 }
index f8c5fc74a33b51dbe5c969f0a427b4c886879c11..a27251c9a8bb0fba0169e8840e40b6f9362e6174 100644 (file)
@@ -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)
 {
@@ -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];
@@ -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) */
@@ -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 {
@@ -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;
 
@@ -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;
index cf49f8a97fb7e339c38923f35d4559c334a292b4..dec3bfd2353ced9b48599983d7875cc44825bbe8 100644 (file)
@@ -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);