From: Peng Tao <bergwolf@gmail.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-kernel@vger.kernel.org, Peng Tao <bergwolf@gmail.com>,
Andreas Dilger <andreas.dilger@intel.com>
Subject: [PATCH 2/4] staging/lustre/obdclass: read jobid from proc
Date: Wed, 30 Oct 2013 19:30:34 +0800 [thread overview]
Message-ID: <1383132636-8952-2-git-send-email-bergwolf@gmail.com> (raw)
In-Reply-To: <1383132636-8952-1-git-send-email-bergwolf@gmail.com>
so that we can get rid of cfs_get_environ() that needs access_process_vm() that
is a core mm function and is not available on some architectures.
Reviewed-by: Niu Yawei <yawei.niu@intel.com>
Signed-off-by: Peng Tao <bergwolf@gmail.com>
Signed-off-by: Andreas Dilger <andreas.dilger@intel.com>
---
drivers/staging/lustre/lustre/obdclass/class_obd.c | 119 +++++++++++++++++++-
1 file changed, 115 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c
index b1024a6..99ce863 100644
--- a/drivers/staging/lustre/lustre/obdclass/class_obd.c
+++ b/drivers/staging/lustre/lustre/obdclass/class_obd.c
@@ -96,8 +96,117 @@ EXPORT_SYMBOL(obd_dirty_transit_pages);
char obd_jobid_var[JOBSTATS_JOBID_VAR_MAX_LEN + 1] = JOBSTATS_DISABLE;
EXPORT_SYMBOL(obd_jobid_var);
-/* Get jobid of current process by reading the environment variable
- * stored in between the "env_start" & "env_end" of task struct.
+static char *self_environ_file = "/proc/self/environ";
+static int obd_get_environ(const char *key, char *value, int *val_len)
+{
+ struct mm_struct *mm;
+ struct path path;
+ struct file *filp = NULL;
+ int buf_len = PAGE_CACHE_SIZE;
+ int key_len = strlen(key);
+ char *buffer = NULL;
+ loff_t pos = 0;
+ int rc;
+
+ /*
+ * test mm->mmap_sem to avoid deadlock if this ever gets called from
+ * mmap code.
+ */
+ mm = get_task_mm(current);
+ if (!mm)
+ return -EINVAL;
+ if (down_read_trylock(&mm->mmap_sem) == 0) {
+ mmput(mm);
+ return -EDEADLK;
+ }
+ up_read(&mm->mmap_sem);
+ mmput(mm);
+
+ buffer = kmalloc(buf_len, GFP_NOIO);
+ if (!buffer)
+ return -ENOMEM;
+
+ rc = kern_path(self_environ_file, LOOKUP_FOLLOW, &path);
+ if (rc)
+ goto out;
+
+ filp = dentry_open(&path, O_RDONLY, current_cred());
+ if (IS_ERR(filp)) {
+ rc = PTR_ERR(filp);
+ filp = NULL;
+ goto out;
+ }
+
+ /* loop reading... */
+ while (1) {
+ int scan_len, this_len;
+ char *env_start, *env_end;
+ rc = kernel_read(filp, pos, buffer, buf_len);
+ if (rc <= 0)
+ break;
+
+ pos += rc;
+ /* Parse the buffer to find out the specified key/value pair.
+ * The "key=value" entries are separated by '\0'. */
+ env_start = buffer;
+ scan_len = this_len = rc;
+ while (scan_len) {
+ char *entry;
+ int entry_len;
+
+ env_end = memscan(env_start, '\0', scan_len);
+ LASSERT(env_end >= env_start &&
+ env_end <= env_start + scan_len);
+
+ /* The last entry of this buffer cross the buffer
+ * boundary, reread it in next cycle. */
+ if (unlikely(env_end - env_start == scan_len)) {
+ /* This entry is too large to fit in buffer */
+ if (unlikely(scan_len == this_len)) {
+ rc = -EINVAL;
+ CWARN("Environment variable '%s' too long: rc = %d\n",
+ key, rc);
+ goto out;
+ }
+ pos -= scan_len;
+ break;
+ }
+
+ entry = env_start;
+ entry_len = env_end - env_start;
+
+ /* Key length + length of '=' */
+ if (entry_len > key_len + 1 &&
+ !memcmp(entry, key, key_len)) {
+ entry += key_len + 1;
+ entry_len -= key_len + 1;
+ /* The 'value' buffer passed in is too small.*/
+ if (entry_len >= *val_len)
+ GOTO(out, rc = -EOVERFLOW);
+
+ memcpy(value, entry, entry_len);
+ *val_len = entry_len;
+ rc = 0;
+ goto out;
+ }
+
+ scan_len -= (env_end - env_start + 1);
+ env_start = env_end + 1;
+ }
+ }
+ if (rc >= 0)
+ rc = -ENOENT;
+out:
+ if (filp)
+ fput(filp);
+ if (buffer)
+ kfree(buffer);
+ return rc;
+}
+
+/*
+ * Get jobid of current process by reading the environment variable
+ * from /proc/self/environ.
*
* TODO:
* It's better to cache the jobid for later use if there is any
@@ -126,14 +235,14 @@ int lustre_get_jobid(char *jobid)
return 0;
}
- rc = cfs_get_environ(obd_jobid_var, jobid, &jobid_len);
+ rc = obd_get_environ(obd_jobid_var, jobid, &jobid_len);
if (rc) {
if (rc == -EOVERFLOW) {
/* For the PBS_JOBID and LOADL_STEP_ID keys (which are
* variable length strings instead of just numbers), it
* might make sense to keep the unique parts for JobID,
* instead of just returning an error. That means a
- * larger temp buffer for cfs_get_environ(), then
+ * larger temp buffer for obd_get_environ(), then
* truncating the string at some separator to fit into
* the specified jobid_len. Fix later if needed. */
static bool printed;
@@ -149,6 +258,8 @@ int lustre_get_jobid(char *jobid)
"Get jobid for (%s) failed: rc = %d\n",
obd_jobid_var, rc);
}
+ } else {
+ CDEBUG(D_INFO, "Got jobid for (%s) value (%s)\n", obd_jobid_var, jobid);
}
return rc;
}
--
1.7.9.5
next prev parent reply other threads:[~2013-10-30 11:30 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-30 11:30 [PATCH 1/4] staging/lustre/llite: cache jobid in lu_env Peng Tao
2013-10-30 11:30 ` Peng Tao [this message]
2013-10-30 13:21 ` [PATCH 2/4] staging/lustre/obdclass: read jobid from proc Greg Kroah-Hartman
2013-10-30 13:31 ` Peng Tao
2013-10-30 14:20 ` Greg Kroah-Hartman
2013-10-30 15:15 ` Peng Tao
2014-02-04 6:12 ` Oleg Drokin
2014-02-04 16:57 ` Greg Kroah-Hartman
2014-02-04 17:27 ` Oleg Drokin
2013-10-30 11:30 ` [PATCH 3/4] staging/lustre: remove cfs_get_environ and cfs_access_process_vm Peng Tao
2013-10-30 11:30 ` [PATCH 4/4] staging/lustre: enable build on MIPS/XTENSA/SUPERH Peng Tao
2013-10-30 13:19 ` [PATCH 1/4] staging/lustre/llite: cache jobid in lu_env Greg Kroah-Hartman
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=1383132636-8952-2-git-send-email-bergwolf@gmail.com \
--to=bergwolf@gmail.com \
--cc=andreas.dilger@intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
/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.