linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Boaz Harrosh <bharrosh@panasas.com>
To: Andrew Morton <akpm@linux-foundation.org>,
	Oleg Nesterov <oleg@redhat.com>,
	Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>,
	<linux-security-module@vger.kernel.org>,
	Ingo Molnar <mingo@elte.hu>,
	Peter Zijlstra <a.p.zijlstra@chello.nl>,
	Paul Turner <pjt@google.com>,
	Thomas Gleixner <tglx@linutronix.de>
Cc: linux-fsdevel <linux-fsdevel@vger.kernel.org>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	NFS list <linux-nfs@vger.kernel.org>,
	Trond Myklebust <Trond.Myklebust@netapp.com>,
	"Bhamare, Sachin" <sbhamare@panasas.com>,
	David Howells <dhowells@redhat.com>,
	Eric Paris <eparis@redhat.com>,
	"Srivatsa S. Bhat" <srivatsa.bhat@linux.vnet.ibm.com>,
	Kay Sievers <kay.sievers@vrfy.org>,
	James Morris <jmorris@namei.org>,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	Greg KH <gregkh@linuxfoundation.org>,
	"Rafael J. Wysocki" <rjw@sisk.pl>,
	"keyrings@linux-nfs.org" <keyrings@linux-nfs.org>
Subject: [PATCH 5/6] kmod: Add new call_usermodehelper_timeout() API
Date: Mon, 26 Mar 2012 19:13:26 -0700	[thread overview]
Message-ID: <4F712246.6030201@panasas.com> (raw)
In-Reply-To: <4F711EA2.4030608@panasas.com>


In the blasphemous occasions that the Kernel must call a user-mode program
half of the times it is more robust to not wait forever but limit the wait
for a specified timeout.

So add a new  call_usermodehelper_timeout() that implements that.
(Users of this new API will be added once this API is in mainline)

call_usermodehelper_fns() is added an extra timeout parameter which
is then implemented in call_usermodehelper_exec. The few users of
call_usermodehelper_fns() are also changed in this patch.

Also an gfp_t parameter is added, for finer allocation control

The code in call_usermodehelper_exec is simplified by the use of
the all-mighty wait_for_completion_timeout_state() which is able
to wait in all the different modes. See:
	completion: Add wait_for_completion_timeout_state()

Should some wait-forever callers today, be converted to this new
schema?

CC: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
---
 fs/exec.c                   |    4 ++--
 include/linux/kmod.h        |   19 ++++++++++++++-----
 kernel/kmod.c               |   24 ++++++++++++------------
 kernel/sys.c                |    2 +-
 security/keys/request_key.c |    2 +-
 5 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index 23559c2..8789ba8 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -2185,8 +2185,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
 		}
 
 		retval = call_usermodehelper_fns(helper_argv[0], helper_argv,
-					NULL, UMH_WAIT_EXEC, umh_pipe_setup,
-					NULL, &cprm);
+					NULL, UMH_WAIT_EXEC, 0, 0,
+					umh_pipe_setup, NULL, &cprm);
 		argv_free(helper_argv);
 		if (retval) {
  			printk(KERN_INFO "Core dump to %s pipe failed\n",
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index ae3f9623..4d9f202 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -60,21 +60,30 @@ struct subprocess_info {
 	char **argv;
 	char **envp;
 	int wait;
+	unsigned long timeout;
 	int retval;
 	int (*init)(struct subprocess_info *info, struct cred *new);
 	void (*cleanup)(struct subprocess_info *info);
 	void *data;
 };
 
-extern int
-call_usermodehelper_fns(char *path, char **argv, char **envp, int wait,
-			int (*init)(struct subprocess_info *info, struct cred *new),
-			void (*cleanup)(struct subprocess_info *), void *data);
+extern int call_usermodehelper_fns(char *path, char **argv, char **envp,
+	int wait, unsigned long timeout, gfp_t gfp,
+	int (*init)(struct subprocess_info *info, struct cred *new),
+	void (*cleanup)(struct subprocess_info *), void *data);
 
 static inline int
 call_usermodehelper(char *path, char **argv, char **envp, int wait)
 {
-	return call_usermodehelper_fns(path, argv, envp, wait,
+	return call_usermodehelper_fns(path, argv, envp, wait, 0, 0,
+				       NULL, NULL, NULL);
+}
+
+static inline int
+call_usermodehelper_timeout(char *path, char **argv, char **envp,
+			    int wait, unsigned long timeout, gfp_t gfp)
+{
+	return call_usermodehelper_fns(path, argv, envp, wait, timeout, gfp,
 				       NULL, NULL, NULL);
 }
 
diff --git a/kernel/kmod.c b/kernel/kmod.c
index b404f99..588cb6f 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -90,7 +90,7 @@ static int call_modprobe(char *module_name, int wait)
 	argv[4] = NULL;
 
 	return call_usermodehelper_fns(modprobe_path, argv, envp,
-		wait | UMH_KILLABLE, NULL, free_modprobe_argv, NULL);
+		wait | UMH_KILLABLE, 0, 0, NULL, free_modprobe_argv, NULL);
 free_argv:
 	kfree(argv);
 out:
@@ -522,6 +522,7 @@ void call_usermodehelper_setfns(struct subprocess_info *info,
 int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait)
 {
 	DECLARE_COMPLETION_ONSTACK(done);
+	int wait_state;
 	int retval = 0;
 
 	helper_lock();
@@ -540,19 +541,15 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait)
 	if (wait == UMH_NO_WAIT)	/* task has freed sub_info */
 		goto unlock;
 
-	if (wait & UMH_KILLABLE) {
-		retval = wait_for_completion_killable(&done);
-		if (!retval)
-			goto wait_done;
-
+	wait_state = (wait & UMH_KILLABLE) ? TASK_KILLABLE : 0;
+	retval = wait_for_completion_timeout_state(&done, sub_info->timeout,
+						   wait_state);
+	if (unlikely(retval)) {
 		/* umh_complete() will see NULL and free sub_info */
 		if (xchg(&sub_info->complete, NULL))
 			goto unlock;
-		/* fallthrough, umh_complete() was already called */
 	}
 
-	wait_for_completion(&done);
-wait_done:
 	retval = sub_info->retval;
 out:
 	call_usermodehelper_freeinfo(sub_info);
@@ -561,13 +558,15 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, int wait)
 	return retval;
 }
 
-int call_usermodehelper_fns(
-	char *path, char **argv, char **envp, int wait,
+int call_usermodehelper_fns(char *path, char **argv, char **envp,
+	int wait, unsigned long timeout, gfp_t gfp_mask,
 	int (*init)(struct subprocess_info *info, struct cred *new),
 	void (*cleanup)(struct subprocess_info *), void *data)
 {
 	struct subprocess_info *info;
-	gfp_t gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
+
+	if (!gfp_mask)
+		gfp_mask = (wait == UMH_NO_WAIT) ? GFP_ATOMIC : GFP_KERNEL;
 
 	info = call_usermodehelper_setup(path, argv, envp, gfp_mask);
 
@@ -575,6 +574,7 @@ int call_usermodehelper_fns(
 		return -ENOMEM;
 
 	call_usermodehelper_setfns(info, init, cleanup, data);
+	info->timeout = timeout;
 
 	return call_usermodehelper_exec(info, wait);
 }
diff --git a/kernel/sys.c b/kernel/sys.c
index 37b1971..16d14d1 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -2020,7 +2020,7 @@ int orderly_poweroff(bool force)
 		goto out;
 	}
 
-	ret = call_usermodehelper_fns(argv[0], argv, envp, UMH_NO_WAIT,
+	ret = call_usermodehelper_fns(argv[0], argv, envp, UMH_NO_WAIT, 0, 0,
 				      NULL, argv_cleanup, NULL);
 out:
 	if (likely(!ret))
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 000e750..aa94dbb 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -93,7 +93,7 @@ static void umh_keys_cleanup(struct subprocess_info *info)
 static int call_usermodehelper_keys(char *path, char **argv, char **envp,
 					struct key *session_keyring, int wait)
 {
-	return call_usermodehelper_fns(path, argv, envp, wait,
+	return call_usermodehelper_fns(path, argv, envp, wait, 0, 0,
 				       umh_keys_init, umh_keys_cleanup,
 				       key_get(session_keyring));
 }
-- 
1.7.6.5



  parent reply	other threads:[~2012-03-27  2:14 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-20 23:18 [PATCHSET 0/4] kmod: Optional timeout on the wait in call_usermodehelper_exec Boaz Harrosh
2012-03-20 23:23 ` [PATCH 1/4] kmod: Un-export call_usermodehelper_freeinfo() Boaz Harrosh
2012-03-20 23:26 ` [PATCH 2/4] kmod: Convert two call sites to call_usermodehelper_fns() Boaz Harrosh
2012-03-22  3:00   ` James Morris
2012-03-20 23:28 ` [PATCH 3/4] kmod: Move call_usermodehelper_fns() to .c file and unexport it's helpers Boaz Harrosh
2012-03-20 23:32 ` [RFC 4/4] {RFC} kmod.c: Add new call_usermodehelper_timeout() API Boaz Harrosh
2012-03-22  2:44   ` Boaz Harrosh
2012-03-22  2:48   ` Boaz Harrosh
2012-03-22  2:52     ` Boaz Harrosh
2012-03-22 11:48     ` [RFC 4/4] {RFC} kmod.c: Add new call_usermodehelper_timeout()API Tetsuo Handa
2012-03-22 14:27     ` [RFC 4/4] {RFC} kmod.c: Add new call_usermodehelper_timeout() API Oleg Nesterov
2012-03-22 14:42       ` Oleg Nesterov
2012-03-22 19:08       ` Boaz Harrosh
2012-03-22 22:16         ` [RFC 4/4] {RFC} kmod.c: Add new call_usermodehelper_timeout()API Tetsuo Handa
2012-03-23  4:48           ` Boaz Harrosh
2012-03-23  5:23             ` Tetsuo Handa
2012-03-23 16:30             ` Oleg Nesterov
2012-03-23 13:34         ` [RFC 4/4] {RFC} kmod.c: Add new call_usermodehelper_timeout() API Oleg Nesterov
2012-03-21 15:35 ` [PATCHSET 0/4] kmod: Optional timeout on the wait in call_usermodehelper_exec Greg KH
2012-03-22  0:18   ` Boaz Harrosh
2012-03-22  0:31     ` Myklebust, Trond
2012-03-22  1:18       ` Boaz Harrosh
2012-03-27  1:57 ` [PATCHSET 0/6 version 2] " Boaz Harrosh
2012-03-27  2:00   ` [PATCH 1/6] kmod: Unexport call_usermodehelper_freeinfo() Boaz Harrosh
2012-03-27  2:02   ` [PATCH 2/6] kmod: Convert two call sites to call_usermodehelper_fns() Boaz Harrosh
2012-03-27  2:04   ` [PATCH 3/6] kmod: Move call_usermodehelper_fns() to .c file and unexport all it's helpers Boaz Harrosh
2012-03-27  2:06   ` [PATCH 4/6 OPTION-A] completion: Add new wait_for_completion_timeout_state Boaz Harrosh
2012-03-27  2:33     ` [PATCH 4/6 OPTION-A version 3] " Boaz Harrosh
2012-03-27  8:11       ` Peter Zijlstra
2012-03-28 18:19         ` Boaz Harrosh
2012-03-28 18:25           ` Peter Zijlstra
2012-03-28 17:38       ` Oleg Nesterov
2012-03-27  2:09   ` [PATCH 4/6 option-B] kmod: add new wait_for_completion_timeout_state() helper Boaz Harrosh
2012-03-27  2:13   ` Boaz Harrosh [this message]
2012-03-27 15:43     ` [PATCH 5/6] kmod: Add new call_usermodehelper_timeout() API Oleg Nesterov
2012-03-28 17:04       ` Oleg Nesterov
2012-03-27  2:15   ` [PATCH 6/6] kmod: optional: Convert the use of xchg to a kref Boaz Harrosh
2012-03-28 16:35     ` Oleg Nesterov
2012-03-27 21:07   ` [PATCHSET 0/6 version 2] kmod: Optional timeout on the wait in call_usermodehelper_exec Andrew Morton
2012-03-28 20:19     ` Oleg Nesterov
2012-03-28 21:42       ` Boaz Harrosh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4F712246.6030201@panasas.com \
    --to=bharrosh@panasas.com \
    --cc=Trond.Myklebust@netapp.com \
    --cc=a.p.zijlstra@chello.nl \
    --cc=akpm@linux-foundation.org \
    --cc=dhowells@redhat.com \
    --cc=ebiederm@xmission.com \
    --cc=eparis@redhat.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jmorris@namei.org \
    --cc=kay.sievers@vrfy.org \
    --cc=keyrings@linux-nfs.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=oleg@redhat.com \
    --cc=penguin-kernel@I-love.SAKURA.ne.jp \
    --cc=pjt@google.com \
    --cc=rjw@sisk.pl \
    --cc=sbhamare@panasas.com \
    --cc=srivatsa.bhat@linux.vnet.ibm.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).