forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
staging/lustre/obdclass: read jobid from proc
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. Signed-off-by: Peng Tao <bergwolf@gmail.com>
- Loading branch information
Showing
1 changed file
with
95 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -96,6 +96,98 @@ EXPORT_SYMBOL(obd_dirty_transit_pages); | |
char obd_jobid_var[JOBSTATS_JOBID_VAR_MAX_LEN + 1] = JOBSTATS_DISABLE; | ||
EXPORT_SYMBOL(obd_jobid_var); | ||
|
||
static char *self_environ_file = "/proc/self/environ"; | ||
static int obd_get_environ(const char *key, char *value, int *val_len) | ||
{ | ||
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; | ||
|
||
buffer = kmalloc(buf_len, GFP_USER); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
bergwolf
Author
Owner
|
||
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)) { | ||
CERROR("Too long env variable.\n"); | ||
This comment has been minimized.
Sorry, something went wrong.
adilger
|
||
rc = -EINVAL; | ||
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 | ||
* stored in between the "env_start" & "env_end" of task struct. | ||
* | ||
|
@@ -126,7 +218,7 @@ 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 | ||
|
@@ -149,6 +241,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; | ||
} | ||
|
I'm not sure if GFP_USER is safe here. Have you checked where lustre_get_env() is called?