All of lore.kernel.org
 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: 62+ 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:18 ` Boaz Harrosh
2012-03-20 23:23 ` [PATCH 1/4] kmod: Un-export call_usermodehelper_freeinfo() Boaz Harrosh
2012-03-20 23:23   ` Boaz Harrosh
2012-03-20 23:26 ` [PATCH 2/4] kmod: Convert two call sites to call_usermodehelper_fns() Boaz Harrosh
2012-03-20 23:26   ` Boaz Harrosh
2012-03-22  3:00   ` James Morris
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
     [not found]       ` <201203241028.IGJ09825.MtOVFHFJQSLOFO@I-love.SAKURA.ne.jp>
     [not found]         ` <4F6D35F0.2020808@panasas.com>
     [not found]           ` <20120323200028.fadf49f8.akpm@linux-foundation.org>
     [not found]             ` <20120324145308.GA10023@redhat.com>
     [not found]               ` <201205191121.BIF57837.FHFOtMOLJQSOFV@I-love.SAKURA.ne.jp>
     [not found]                 ` <4FB7170F.7070807@panasas.com>
2012-05-21 17:01                   ` call_usermodehelper && check_hung_uninterruptible_tasks Oleg Nesterov
2012-05-21 18:24                     ` Oleg Nesterov
     [not found]                 ` <87fwau4aag.fsf@rustcorp.com.au>
2012-05-21 17:34                   ` UMH_WAIT_EXEC->UMH_WAIT_PROC deadlock Oleg Nesterov
2012-05-21 18:12                     ` Oleg Nesterov
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:27       ` Oleg Nesterov
2012-03-22 14:42       ` 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  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-23 13:34           ` 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  0:31       ` Myklebust, Trond
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:00     ` 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:06     ` 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-27  8:11         ` Peter Zijlstra
2012-03-28 18:19         ` Boaz Harrosh
2012-03-28 18:19           ` Boaz Harrosh
2012-03-28 18:25           ` Peter Zijlstra
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-27 15:43       ` 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-27 21:07     ` 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.