<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<p style="margin-top:0;margin-bottom:0">So can we set session ids?&nbsp; Can we make them the same across many nodes?&nbsp; It doesn't sound like it.&nbsp; That's a basic requirement.&nbsp; We need more than just &quot;kernel provided&nbsp;ID which is unique to process set on a node&quot;.&nbsp;
 The point of jobstats is to be able to collect info on all of a job, and many jobs will span many nodes.&nbsp; (We also have &gt; 1 job per node in other cases.)</p>
<p style="margin-top:0;margin-bottom:0"><br>
</p>
<p style="margin-top:0;margin-bottom:0"></p>
<p style="margin-top:0;margin-bottom:0">- Patrick</p>
</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> NeilBrown &lt;neilb@suse.com&gt;<br>
<b>Sent:</b> Wednesday, March 13, 2019 7:34:05 PM<br>
<b>To:</b> Patrick Farrell; Andreas Dilger<br>
<b>Cc:</b> Lustre Development List<br>
<b>Subject:</b> Re: [PATCH 37/37] lustre: obd_sysfs: error-check value stored in jobid_var</font>
<div>&nbsp;</div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText"><br>
Hi Patrick,<br>
&nbsp;I agree that &quot;something that should live in struct_task&quot; is the sort of<br>
&nbsp;answer that would be nice, but I don't think it can be justified.<br>
<br>
&nbsp;A &quot;session&quot; in the sense of &quot;getsid&quot; and &quot;setsid&quot; is traditionally a<br>
&nbsp;login session, but since the invention of windowing systems it is one<br>
&nbsp;terminal window.<br>
&nbsp;So if you<br>
&nbsp;&nbsp;&nbsp; grep NSsid /proc/self/status<br>
&nbsp;in different windows you will see different session ids.&nbsp; All processes<br>
&nbsp;in that window will have the same session id unless something<br>
&nbsp;explicitly creates a new session - few things do that.<br>
<br>
&nbsp;If you want to explicitly create a new session, you can use &quot;setsid&quot;.<br>
&nbsp;So<br>
&nbsp;&nbsp;&nbsp; setsid grep NSsid /proc/self/status<br>
&nbsp;will always show a new session id.<br>
<br>
&nbsp;Considering you sketch, the &quot;unique parent&quot; is already very likely to<br>
&nbsp;be in a session that no other job is in.<br>
&nbsp;If you run multiple jobs from the one terminal window (is they likely?)<br>
&nbsp;then the will all be in the same session unless you run<br>
&nbsp;&nbsp;&nbsp; setsid run-my-job<br>
<br>
&nbsp;The session (and anything we associated with it) will apply to all<br>
&nbsp;children and grandchild etc.<br>
&nbsp;There is no need for a timeout beyond what the code already has - it<br>
&nbsp;checks every 5 minutes to see if the session is still active, and<br>
&nbsp;forgets any inactive session.&nbsp; There is no risk of a new session being<br>
&nbsp;confused with an old session that no longer exists, even if they have<br>
&nbsp;the same number.<br>
<br>
&nbsp;I hope that clarifies for you.<br>
<br>
Thanks,<br>
NeilBrown<br>
<br>
<br>
On Fri, Mar 01 2019, Patrick Farrell wrote:<br>
<br>
&gt; The definition of &quot;session&quot; matters here.&nbsp; It is increasingly common to run multiple jobs on a node at the same time, and the desire to distinguish between them is also significant.&nbsp; So we can't have just one session.<br>
&gt;<br>
&gt; I believe this is part of why it was chosen to put this information in user space, associated with a particular process.<br>
&gt;<br>
&gt; So we need a solution that can meet that requirement or the broader HPC world will just ignore us.<br>
&gt;<br>
&gt; Perhaps we could use the new jobid cache functionality here.&nbsp; A sketch:<br>
&gt;<br>
&gt; Have the parent - I believe there would be a unique parent for every set of job processes - register the ID (via this proc variable) and we would apply it to all children (what about grandchildren, etc...).&nbsp; Then set timeouts to something like 24 or 48 hours,
 and but also use (or add if it's not present?) the functionality to deregister job ids at job exit.&nbsp; So the timeout is only for cleanup.<br>
&gt;<br>
&gt; Although, the more I talk about this, the more this feels like something that should live in struct_task and be set from user space and managed by the kernel...<br>
&gt; ________________________________<br>
&gt; From: lustre-devel &lt;lustre-devel-bounces@lists.lustre.org&gt; on behalf of Andreas Dilger &lt;adilger@whamcloud.com&gt;<br>
&gt; Sent: Friday, March 1, 2019 2:32:00 AM<br>
&gt; To: NeilBrown<br>
&gt; Cc: Lustre Development List<br>
&gt; Subject: Re: [lustre-devel] [PATCH 37/37] lustre: obd_sysfs: error-check value stored in jobid_var<br>
&gt;<br>
&gt; On Feb 28, 2019, at 19:35, NeilBrown &lt;neilb@suse.com&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; On Wed, Feb 27 2019, Andreas Dilger wrote:<br>
&gt;&gt;<br>
&gt;&gt;&gt; On Feb 18, 2019, at 17:09, NeilBrown &lt;neilb@suse.com&gt; wrote:<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; The jobid_var sysfs attribute only has 3 meaningful values.<br>
&gt;&gt;&gt;&gt; Other values cause lustre_get_jobid() to return an error<br>
&gt;&gt;&gt;&gt; which is uniformly ignored.<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; To improve usability and resilience, check that the value<br>
&gt;&gt;&gt;&gt; written is acceptable before storing it.<br>
&gt;&gt;&gt;&gt;<br>
&gt;&gt;&gt;&gt; Signed-off-by: NeilBrown &lt;neilb@suse.com&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; This will no longer be true once <a href="https://review.whamcloud.com/31691">
https://review.whamcloud.com/31691</a><br>
&gt;&gt;&gt; commit 6488c0ec57de (&quot;LU-10698 obdclass: allow specifying complex jobids&quot;)<br>
&gt;&gt;<br>
&gt;&gt; Actually it will.&nbsp; That patch changes the use of jobid_name, my patch<br>
&gt;&gt; restricts the values of jobid_var.<br>
&gt;&gt;<br>
&gt;&gt; I just realized why it is called &quot;jobid_var&quot; - in OpenSFS lustre, it can<br>
&gt;&gt; be an environment variable name.&nbsp; In drivers/staging lustre it cannot,<br>
&gt;&gt; so the name is a little odd.<br>
&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Currently the &quot;%j&quot; function was removed from the kernel client, even<br>
&gt;&gt;&gt; though there is no technical reason it can't work (i.e. all of the code<br>
&gt;&gt;&gt; to implement it is available and exported).&nbsp; This is actually super<br>
&gt;&gt;&gt; useful for HPC cluster administrators to monitor per-job IO bandwidth<br>
&gt;&gt;&gt; and IOPS on the server, and something that I think should be restored.<br>
&gt;&gt;<br>
&gt;&gt; I think that you probably need to let go of that desire - I don't think<br>
&gt;&gt; it is going to happen.&nbsp; While the code may, as you say, work - it is<br>
&gt;&gt; easy to dislike that approach, and would be hard to push against such<br>
&gt;&gt; resistance.<br>
&gt;&gt;<br>
&gt;&gt; I have an alternate approach, patch below.&nbsp; Instead of<br>
&gt;&gt; export LUSTRE_JOBID=foobar<br>
&gt;&gt; and process can run<br>
&gt;&gt; echo foobar &gt; /sys/fs/lustre/jobid_this_session<br>
&gt;&gt;<br>
&gt;&gt; and it will affect all processes in the current &quot;session&quot;.<br>
&gt;&gt;<br>
&gt;&gt; Could you warm to this approach at all?<br>
&gt;<br>
&gt; This is the best alternative that I've seen so far.&nbsp; That said, the choice<br>
&gt; of storing the JobID as an environment variable wasn't something that we<br>
&gt; invented ourselves, but rather this is what the various job schedulers do<br>
&gt; when a job is first started, and the code to extract the JobID out of the<br>
&gt; process environment was what we implemented to work within the constraints<br>
&gt; that were given to us.&nbsp; The benefit of course is that we don't depend on<br>
&gt; some external process to be run for every process to extract the environment<br>
&gt; variable from the kernel memory and send it back to us.<br>
&gt;<br>
&gt; Allowing different processes to have different JobIDs on a single node is<br>
&gt; definitely a requirement for most environments these days, and so far this<br>
&gt; is the only solution that has allowed that to work.<br>
&gt;<br>
&gt; James is more familiar with the production side of the house, so I'll let<br>
&gt; him comment on how easy/hard it would be to get this kind of change added<br>
&gt; to the per-job preamble script so that it is set for all processes.<br>
&gt;<br>
&gt; Cheers, Andreas<br>
&gt;<br>
&gt;&gt; From: NeilBrown &lt;neilb@suse.com&gt;<br>
&gt;&gt; Subject: [PATCH] lustre: obdclass: allow per-session jobids.<br>
&gt;&gt;<br>
&gt;&gt; Lustre includes a jobid in all RPC message sent to the server.&nbsp; This<br>
&gt;&gt; is used to collected per-job statistics, where a &quot;job&quot; can involve<br>
&gt;&gt; multiple processes on multiple nodes in a cluster.<br>
&gt;&gt;<br>
&gt;&gt; Nodes in a cluster can be running processes for multiple jobs, so it<br>
&gt;&gt; is best if different processes can have different jobids, and that<br>
&gt;&gt; processes on different nodes can have the same job id.<br>
&gt;&gt;<br>
&gt;&gt; This is not currently possible with the drivers/staging code.<br>
&gt;&gt;<br>
&gt;&gt; Lustre traditionally uses an environment variable to name a job, but<br>
&gt;&gt; having the kernel reach into the address space of a process to find<br>
&gt;&gt; that environment variable is seen by some developers to be an<br>
&gt;&gt; unacceptable design choice.<br>
&gt;&gt;<br>
&gt;&gt; This patch provides an alternate method, leveraging the concept of a<br>
&gt;&gt; &quot;session id&quot;, as set with setsid().&nbsp; Each login session already gets a<br>
&gt;&gt; unique sid which is preserved for all processes in that session unless<br>
&gt;&gt; explicitly changed (with setsid(1)).<br>
&gt;&gt; When a process in a session writes to<br>
&gt;&gt; /sys/fs/lustre/jobid_this_session, the string becomes the name for<br>
&gt;&gt; that session.<br>
&gt;&gt; If jobid_var is set to &quot;manual&quot;, then the per-session jobid is used<br>
&gt;&gt; for the jobid for all requests from processes in that session.<br>
&gt;&gt;<br>
&gt;&gt; When a session ends, the jobid information will be purged within 5<br>
&gt;&gt; minutes.<br>
&gt;&gt;<br>
&gt;&gt; Signed-off-by: NeilBrown &lt;neilb@suse.com&gt;<br>
&gt;&gt; ---<br>
&gt;&gt; .../staging/lustre/lustre/include/lprocfs_status.h |&nbsp;&nbsp; 1 &#43;<br>
&gt;&gt; drivers/staging/lustre/lustre/include/obd_class.h&nbsp; |&nbsp;&nbsp; 3 &#43;<br>
&gt;&gt; drivers/staging/lustre/lustre/obdclass/class_obd.c | 160 &#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;&#43;-<br>
&gt;&gt; drivers/staging/lustre/lustre/obdclass/obd_sysfs.c |&nbsp; 41 &#43;&#43;&#43;&#43;&#43;&#43;<br>
&gt;&gt; 4 files changed, 204 insertions(&#43;), 1 deletion(-)<br>
&gt;&gt;<br>
&gt;&gt; diff --git a/drivers/staging/lustre/lustre/include/lprocfs_status.h b/drivers/staging/lustre/lustre/include/lprocfs_status.h<br>
&gt;&gt; index 8565c28f08ee..1335a5722903 100644<br>
&gt;&gt; --- a/drivers/staging/lustre/lustre/include/lprocfs_status.h<br>
&gt;&gt; &#43;&#43;&#43; b/drivers/staging/lustre/lustre/include/lprocfs_status.h<br>
&gt;&gt; @@ -370,6 &#43;370,7 @@ static inline void s2dhms(struct dhms *ts, time64_t secs64)<br>
&gt;&gt; #define JOBSTATS_DISABLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;disable&quot;<br>
&gt;&gt; #define JOBSTATS_PROCNAME_UID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;procname_uid&quot;<br>
&gt;&gt; #define JOBSTATS_NODELOCAL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;nodelocal&quot;<br>
&gt;&gt; &#43;#define JOBSTATS_MANUAL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;manual&quot;<br>
&gt;&gt;<br>
&gt;&gt; /* obd_config.c */<br>
&gt;&gt; void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg));<br>
&gt;&gt; diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h<br>
&gt;&gt; index 50b08c89ecc5..08003f3dd467 100644<br>
&gt;&gt; --- a/drivers/staging/lustre/lustre/include/obd_class.h<br>
&gt;&gt; &#43;&#43;&#43; b/drivers/staging/lustre/lustre/include/obd_class.h<br>
&gt;&gt; @@ -55,6 &#43;55,9 @@ extern rwlock_t obd_dev_lock;<br>
&gt;&gt; struct obd_device *class_exp2obd(struct obd_export *exp);<br>
&gt;&gt; int class_handle_ioctl(unsigned int cmd, unsigned long arg);<br>
&gt;&gt; int lustre_get_jobid(char *jobid);<br>
&gt;&gt; &#43;char *jobid_current(void);<br>
&gt;&gt; &#43;int jobid_set_current(char *jobid);<br>
&gt;&gt; &#43;<br>
&gt;&gt;<br>
&gt;&gt; struct lu_device_type;<br>
&gt;&gt;<br>
&gt;&gt; diff --git a/drivers/staging/lustre/lustre/obdclass/class_obd.c b/drivers/staging/lustre/lustre/obdclass/class_obd.c<br>
&gt;&gt; index 1fcbda128a58..19ce3c858e59 100644<br>
&gt;&gt; --- a/drivers/staging/lustre/lustre/obdclass/class_obd.c<br>
&gt;&gt; &#43;&#43;&#43; b/drivers/staging/lustre/lustre/obdclass/class_obd.c<br>
&gt;&gt; @@ -79,6 &#43;79,144 @@ EXPORT_SYMBOL(at_extra);<br>
&gt;&gt; char obd_jobid_var[JOBSTATS_JOBID_VAR_MAX_LEN &#43; 1] = JOBSTATS_DISABLE;<br>
&gt;&gt; char obd_jobid_node[LUSTRE_JOBID_SIZE &#43; 1];<br>
&gt;&gt;<br>
&gt;&gt; &#43;/*<br>
&gt;&gt; &#43; * Jobid can be set for a session (see setsid(2)) by writing to<br>
&gt;&gt; &#43; * a sysfs file from any process in that session.<br>
&gt;&gt; &#43; * The jobids are stored in a hash table indexed by the relevant<br>
&gt;&gt; &#43; * struct pid.&nbsp; We periodically look for entries where the pid has<br>
&gt;&gt; &#43; * no PIDTYPE_SID tasks any more, and prune them.&nbsp; This happens within<br>
&gt;&gt; &#43; * 5 seconds of a jobid being added, and every 5 minutes when jobids exist,<br>
&gt;&gt; &#43; * but none are added.<br>
&gt;&gt; &#43; */<br>
&gt;&gt; &#43;#define JOBID_EXPEDITED_CLEAN (5 * HZ)<br>
&gt;&gt; &#43;#define JOBID_BACKGROUND_CLEAN (5 * 60 * HZ)<br>
&gt;&gt; &#43;<br>
&gt;&gt; &#43;struct session_jobid {<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; struct pid&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *session;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; struct rhash_head&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; linkage;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; struct rcu_head&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rcu;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; char&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jobid[1];<br>
&gt;&gt; &#43;};<br>
&gt;&gt; &#43;<br>
&gt;&gt; &#43;const static struct rhashtable_params jobid_params = {<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; .key_len&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = sizeof(struct pid *),<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; .key_offset&nbsp;&nbsp;&nbsp;&nbsp; = offsetof(struct session_jobid, session),<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; .head_offset&nbsp;&nbsp;&nbsp; = offsetof(struct session_jobid, linkage),<br>
&gt;&gt; &#43;};<br>
&gt;&gt; &#43;static struct rhashtable session_jobids;<br>
&gt;&gt; &#43;<br>
&gt;&gt; &#43;/*<br>
&gt;&gt; &#43; * jobid_current must be called with rcu_read_lock held.<br>
&gt;&gt; &#43; * if it returns non-NULL, the string can only be used<br>
&gt;&gt; &#43; * until rcu_read_unlock is called.<br>
&gt;&gt; &#43; */<br>
&gt;&gt; &#43;char *jobid_current(void)<br>
&gt;&gt; &#43;{<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; struct pid *sid = current-&gt;signal-&gt;pids[PIDTYPE_SID];<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; struct session_jobid *sj;<br>
&gt;&gt; &#43;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; sj = rhashtable_lookup_fast(&amp;session_jobids, &amp;sid, jobid_params);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; if (sj)<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return sj-&gt;jobid;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; return NULL;<br>
&gt;&gt; &#43;}<br>
&gt;&gt; &#43;<br>
&gt;&gt; &#43;static void jobid_prune_expedite(void);<br>
&gt;&gt; &#43;/*<br>
&gt;&gt; &#43; * jobid_set_current will try to add a new entry<br>
&gt;&gt; &#43; * to the table.&nbsp; If one exists with the same key, the<br>
&gt;&gt; &#43; * jobid will be replaced<br>
&gt;&gt; &#43; */<br>
&gt;&gt; &#43;int jobid_set_current(char *jobid)<br>
&gt;&gt; &#43;{<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; struct pid *sid = current-&gt;signal-&gt;pids[PIDTYPE_SID];<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; struct session_jobid *sj, *origsj;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; int ret;<br>
&gt;&gt; &#43;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; sj = kmalloc(sizeof(*sj) &#43; strlen(jobid), GFP_KERNEL);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; if (!sj)<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ENOMEM;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; rcu_read_lock();<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; sj-&gt;session = get_pid(sid);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; strcpy(sj-&gt;jobid, jobid);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; origsj = rhashtable_lookup_get_insert_fast(&amp;session_jobids,<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;sj-&gt;linkage,<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jobid_params);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; if (origsj == NULL) {<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* successful insert */<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rcu_read_unlock();<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jobid_prune_expedite();<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;&gt; &#43;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; if (IS_ERR(origsj)) {<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; put_pid(sj-&gt;session);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kfree(sj);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rcu_read_unlock();<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return PTR_ERR(origsj);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; ret = rhashtable_replace_fast(&amp;session_jobids,<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;origsj-&gt;linkage,<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;sj-&gt;linkage,<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jobid_params);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; if (ret) {<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; put_pid(sj-&gt;session);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kfree(sj);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rcu_read_unlock();<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ret;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; put_pid(origsj-&gt;session);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; rcu_read_unlock();<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; kfree_rcu(origsj, rcu);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; jobid_prune_expedite();<br>
&gt;&gt; &#43;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>
&gt;&gt; &#43;}<br>
&gt;&gt; &#43;<br>
&gt;&gt; &#43;static void jobid_free(void *vsj, void *arg)<br>
&gt;&gt; &#43;{<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; struct session_jobid *sj = vsj;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; put_pid(sj-&gt;session);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; kfree(sj);<br>
&gt;&gt; &#43;}<br>
&gt;&gt; &#43;<br>
&gt;&gt; &#43;static void jobid_prune(struct work_struct *work);<br>
&gt;&gt; &#43;static DECLARE_DELAYED_WORK(jobid_prune_work, jobid_prune);<br>
&gt;&gt; &#43;static int jobid_prune_expedited;<br>
&gt;&gt; &#43;static void jobid_prune(struct work_struct *work)<br>
&gt;&gt; &#43;{<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; int remaining = 0;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; struct rhashtable_iter iter;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; struct session_jobid *sj;<br>
&gt;&gt; &#43;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; jobid_prune_expedited = 0;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; rhashtable_walk_enter(&amp;session_jobids, &amp;iter);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; rhashtable_walk_start(&amp;iter);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; while ((sj = rhashtable_walk_next(&amp;iter)) != NULL) {<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!hlist_empty(&amp;sj-&gt;session-&gt;tasks[PIDTYPE_SID])) {<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; remaining&#43;&#43;;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (rhashtable_remove_fast(&amp;session_jobids,<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;sj-&gt;linkage, jobid_params) == 0) {<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; put_pid(sj-&gt;session);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kfree_rcu(sj, rcu);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; rhashtable_walk_stop(&amp;iter);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; rhashtable_walk_exit(&amp;iter);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; if (remaining)<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; schedule_delayed_work(&amp;jobid_prune_work, JOBID_BACKGROUND_CLEAN);<br>
&gt;&gt; &#43;}<br>
&gt;&gt; &#43;<br>
&gt;&gt; &#43;static void jobid_prune_expedite(void)<br>
&gt;&gt; &#43;{<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; if (!jobid_prune_expedited) {<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jobid_prune_expedited = 1;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mod_delayed_work(system_wq, &amp;jobid_prune_work, JOBID_EXPEDITED_CLEAN);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;&gt; &#43;}<br>
&gt;&gt; &#43;<br>
&gt;&gt; /* Get jobid of current process from stored variable or calculate<br>
&gt;&gt;&nbsp; * it from pid and user_id.<br>
&gt;&gt;&nbsp; *<br>
&gt;&gt; @@ -108,6 &#43;246,17 @@ int lustre_get_jobid(char *jobid)<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto out_cache_jobid;<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;&gt;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; if (strcmp(obd_jobid_var, JOBSTATS_MANUAL) == 0) {<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char *jid;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rcu_read_lock();<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jid = jobid_current();<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (jid)<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strlcpy(tmp_jobid, jid, sizeof(tmp_jobid));<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rcu_read_unlock();<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (jid)<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto out_cache_jobid;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;&gt; &#43;<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ENOENT;<br>
&gt;&gt;<br>
&gt;&gt; out_cache_jobid:<br>
&gt;&gt; @@ -663,10 &#43;812,13 @@ static int __init obdclass_init(void)<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (err)<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto cleanup_zombie_impexp;<br>
&gt;&gt;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; err = rhashtable_init(&amp;session_jobids, &amp;jobid_params);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; if (err)<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto cleanup_class_handle;<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; err = misc_register(&amp;obd_psdev);<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (err) {<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CERROR(&quot;cannot register OBD miscdevices: err %d\n&quot;, err);<br>
&gt;&gt; -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto cleanup_class_handle;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto cleanup_session_jobids;<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;&gt;<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Default the dirty page cache cap to 1/2 of system memory.<br>
&gt;&gt; @@ -724,6 &#43;876,9 @@ static int __init obdclass_init(void)<br>
&gt;&gt; cleanup_deregister:<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; misc_deregister(&amp;obd_psdev);<br>
&gt;&gt;<br>
&gt;&gt; &#43;cleanup_session_jobids:<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; rhashtable_free_and_destroy(&amp;session_jobids, jobid_free, NULL);<br>
&gt;&gt; &#43;<br>
&gt;&gt; cleanup_class_handle:<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class_handle_cleanup();<br>
&gt;&gt;<br>
&gt;&gt; @@ -743,6 &#43;898,9 @@ static void obdclass_exit(void)<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cl_global_fini();<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lu_global_fini();<br>
&gt;&gt;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; cancel_delayed_work_sync(&amp;jobid_prune_work);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; rhashtable_free_and_destroy(&amp;session_jobids, jobid_free, NULL);<br>
&gt;&gt; &#43;<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; obd_cleanup_caches();<br>
&gt;&gt;<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class_procfs_clean();<br>
&gt;&gt; diff --git a/drivers/staging/lustre/lustre/obdclass/obd_sysfs.c b/drivers/staging/lustre/lustre/obdclass/obd_sysfs.c<br>
&gt;&gt; index 69ccc6a55947..112782e56793 100644<br>
&gt;&gt; --- a/drivers/staging/lustre/lustre/obdclass/obd_sysfs.c<br>
&gt;&gt; &#43;&#43;&#43; b/drivers/staging/lustre/lustre/obdclass/obd_sysfs.c<br>
&gt;&gt; @@ -220,6 &#43;220,7 @@ static ssize_t jobid_var_store(struct kobject *kobj, struct attribute *attr,<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JOBSTATS_DISABLE,<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JOBSTATS_PROCNAME_UID,<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JOBSTATS_NODELOCAL,<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JOBSTATS_MANUAL,<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NULL<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;<br>
&gt;&gt; @@ -263,6 &#43;264,44 @@ static ssize_t jobid_name_store(struct kobject *kobj, struct attribute *attr,<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return count;<br>
&gt;&gt; }<br>
&gt;&gt;<br>
&gt;&gt; &#43;static ssize_t jobid_this_session_show(struct kobject *kobj,<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct attribute *attr,<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char *buf)<br>
&gt;&gt; &#43;{<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; char *jid;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; int ret = -ENOENT;<br>
&gt;&gt; &#43;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; rcu_read_lock();<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; jid = jobid_current();<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; if (jid)<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret = snprintf(buf, PAGE_SIZE, &quot;%s\n&quot;, jid);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; rcu_read_unlock();<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; return ret;<br>
&gt;&gt; &#43;}<br>
&gt;&gt; &#43;<br>
&gt;&gt; &#43;static ssize_t jobid_this_session_store(struct kobject *kobj,<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct attribute *attr,<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const char *buffer,<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size_t count)<br>
&gt;&gt; &#43;{<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; char *jobid;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; int len;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; int ret;<br>
&gt;&gt; &#43;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; if (!count || count &gt; LUSTRE_JOBID_SIZE)<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EINVAL;<br>
&gt;&gt; &#43;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; jobid = kstrndup(buffer, count, GFP_KERNEL);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; if (!jobid)<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ENOMEM;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; len = strcspn(jobid, &quot; \n&quot;);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; jobid[len] = '\0';<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; ret = jobid_set_current(jobid);<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; kfree(jobid);<br>
&gt;&gt; &#43;<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; return ret ?: count;<br>
&gt;&gt; &#43;}<br>
&gt;&gt; &#43;<br>
&gt;&gt; /* Root for /sys/kernel/debug/lustre */<br>
&gt;&gt; struct dentry *debugfs_lustre_root;<br>
&gt;&gt; EXPORT_SYMBOL_GPL(debugfs_lustre_root);<br>
&gt;&gt; @@ -272,6 &#43;311,7 @@ LUSTRE_RO_ATTR(pinger);<br>
&gt;&gt; LUSTRE_RO_ATTR(health_check);<br>
&gt;&gt; LUSTRE_RW_ATTR(jobid_var);<br>
&gt;&gt; LUSTRE_RW_ATTR(jobid_name);<br>
&gt;&gt; &#43;LUSTRE_RW_ATTR(jobid_this_session);<br>
&gt;&gt;<br>
&gt;&gt; static struct attribute *lustre_attrs[] = {<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;lustre_attr_version.attr,<br>
&gt;&gt; @@ -279,6 &#43;319,7 @@ static struct attribute *lustre_attrs[] = {<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;lustre_attr_health_check.attr,<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;lustre_attr_jobid_name.attr,<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;lustre_attr_jobid_var.attr,<br>
&gt;&gt; &#43;&nbsp;&nbsp;&nbsp;&nbsp; &amp;lustre_attr_jobid_this_session.attr,<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;lustre_sattr_timeout.u.attr,<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;lustre_attr_max_dirty_mb.attr,<br>
&gt;&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;lustre_sattr_debug_peer_on_timeout.u.attr,<br>
&gt;&gt; --<br>
&gt;&gt; 2.14.0.rc0.dirty<br>
&gt;&gt;<br>
&gt;<br>
&gt; Cheers, Andreas<br>
&gt; ---<br>
&gt; Andreas Dilger<br>
&gt; CTO Whamcloud<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; lustre-devel mailing list<br>
&gt; lustre-devel@lists.lustre.org<br>
&gt; <a href="http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org">http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org</a><br>
</div>
</span></font></div>
</body>
</html>