@@ -96,6 +96,116 @@ EXPORT_SYMBOL(obd_dirty_transit_pages);
96
96
char obd_jobid_var [JOBSTATS_JOBID_VAR_MAX_LEN + 1 ] = JOBSTATS_DISABLE ;
97
97
EXPORT_SYMBOL (obd_jobid_var );
98
98
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
+
99
209
/* Get jobid of current process by reading the environment variable
100
210
* stored in between the "env_start" & "env_end" of task struct.
101
211
*
@@ -126,7 +236,7 @@ int lustre_get_jobid(char *jobid)
126
236
return 0 ;
127
237
}
128
238
129
- rc = cfs_get_environ (obd_jobid_var , jobid , & jobid_len );
239
+ rc = obd_get_environ (obd_jobid_var , jobid , & jobid_len );
130
240
if (rc ) {
131
241
if (rc == - EOVERFLOW ) {
132
242
/* For the PBS_JOBID and LOADL_STEP_ID keys (which are
@@ -149,6 +259,8 @@ int lustre_get_jobid(char *jobid)
149
259
"Get jobid for (%s) failed: rc = %d\n" ,
150
260
obd_jobid_var , rc );
151
261
}
262
+ } else {
263
+ CDEBUG (D_INFO , "Got jobid for (%s) value (%s)\n" , obd_jobid_var , jobid );
152
264
}
153
265
return rc ;
154
266
}
0 commit comments