Skip to content

Commit e506e96

Browse files
committedOct 24, 2013
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>
1 parent 398d254 commit e506e96

File tree

1 file changed

+113
-1
lines changed

1 file changed

+113
-1
lines changed
 

‎drivers/staging/lustre/lustre/obdclass/class_obd.c

+113-1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,116 @@ EXPORT_SYMBOL(obd_dirty_transit_pages);
9696
char obd_jobid_var[JOBSTATS_JOBID_VAR_MAX_LEN + 1] = JOBSTATS_DISABLE;
9797
EXPORT_SYMBOL(obd_jobid_var);
9898

99+
static char *self_environ_file = "/proc/self/environ";
100+
static int obd_get_environ(const char *key, char *value, int *val_len)
101+
{
102+
struct mm_struct *mm;
103+
struct path path;
104+
struct file *filp = NULL;
105+
int buf_len = PAGE_CACHE_SIZE;
106+
int key_len = strlen(key);
107+
char *buffer = NULL;
108+
loff_t pos = 0;
109+
int rc;
110+
111+
/*
112+
* test mm->mmap_sem to avoid deadlock if this ever gets called from
113+
* mmap code.
114+
*/
115+
mm = get_task_mm(current);
116+
if (!mm)
117+
return -EINVAL;
118+
if (down_read_trylock(&mm->mmap_sem) == 0)
119+
return -EDEADLK;
120+
up_read(&mm->mmap_sem);
121+
mmput(mm);
122+
123+
buffer = kmalloc(buf_len, GFP_NOIO);
124+
if (!buffer)
125+
return -ENOMEM;
126+
127+
rc = kern_path(self_environ_file, LOOKUP_FOLLOW, &path);
128+
if (rc)
129+
goto out;
130+
131+
filp = dentry_open(&path, O_RDONLY, current_cred());
132+
if (IS_ERR(filp)) {
133+
rc = PTR_ERR(filp);
134+
filp = NULL;
135+
goto out;
136+
}
137+
138+
/* loop reading... */
139+
while (1) {
140+
int scan_len, this_len;
141+
char *env_start, *env_end;
142+
rc = kernel_read(filp, pos, buffer, buf_len);
143+
if (rc <= 0)
144+
break;
145+
146+
pos += rc;
147+
/* Parse the buffer to find out the specified key/value pair.
148+
* The "key=value" entries are separated by '\0'. */
149+
env_start = buffer;
150+
scan_len = this_len = rc;
151+
while (scan_len) {
152+
char *entry;
153+
int entry_len;
154+
155+
env_end = memscan(env_start, '\0', scan_len);
156+
LASSERT(env_end >= env_start &&
157+
env_end <= env_start + scan_len);
158+
159+
/* The last entry of this buffer cross the buffer
160+
* boundary, reread it in next cycle. */
161+
if (unlikely(env_end - env_start == scan_len)) {
162+
/* This entry is too large to fit in buffer */
163+
if (unlikely(scan_len == this_len)) {
164+
static bool printed;
165+
rc = -EINVAL;
166+
if (!printed) {
167+
CWARN("Environment variable '%s' too long: rc = %d\n",
168+
key, rc);
169+
printed = true;
170+
}
171+
goto out;
172+
}
173+
pos -= scan_len;
174+
break;
175+
}
176+
177+
entry = env_start;
178+
entry_len = env_end - env_start;
179+
180+
/* Key length + length of '=' */
181+
if (entry_len > key_len + 1 &&
182+
!memcmp(entry, key, key_len)) {
183+
entry += key_len + 1;
184+
entry_len -= key_len + 1;
185+
/* The 'value' buffer passed in is too small.*/
186+
if (entry_len >= *val_len)
187+
GOTO(out, rc = -EOVERFLOW);
188+
189+
memcpy(value, entry, entry_len);
190+
*val_len = entry_len;
191+
rc = 0;
192+
goto out;
193+
}
194+
195+
scan_len -= (env_end - env_start + 1);
196+
env_start = env_end + 1;
197+
}
198+
}
199+
if (rc >= 0)
200+
rc = -ENOENT;
201+
out:
202+
if (filp)
203+
fput(filp);
204+
if (buffer)
205+
kfree(buffer);
206+
return rc;
207+
}
208+
99209
/* Get jobid of current process by reading the environment variable
100210
* stored in between the "env_start" & "env_end" of task struct.
101211
*
@@ -126,7 +236,7 @@ int lustre_get_jobid(char *jobid)
126236
return 0;
127237
}
128238

129-
rc = cfs_get_environ(obd_jobid_var, jobid, &jobid_len);
239+
rc = obd_get_environ(obd_jobid_var, jobid, &jobid_len);
130240
if (rc) {
131241
if (rc == -EOVERFLOW) {
132242
/* For the PBS_JOBID and LOADL_STEP_ID keys (which are
@@ -149,6 +259,8 @@ int lustre_get_jobid(char *jobid)
149259
"Get jobid for (%s) failed: rc = %d\n",
150260
obd_jobid_var, rc);
151261
}
262+
} else {
263+
CDEBUG(D_INFO, "Got jobid for (%s) value (%s)\n", obd_jobid_var, jobid);
152264
}
153265
return rc;
154266
}

0 commit comments

Comments
 (0)