<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">On 02/25/2014 10:42 AM, Sheldon wrote:<br>
    </div>
    <blockquote cite="mid:530C9DB6.5060501@linux.vnet.ibm.com"
      type="cite">
      <meta content="text/html; charset=ISO-8859-1"
        http-equiv="Content-Type">
      <div class="moz-cite-prefix">Not sure RamSession is a good choice.<br>
        <br>
        What's the different between MemcachedSession and RamSession.<br>
        <br>
        Have check the cherrpy doc, does not tell the details.<br>
        <dl class="function">
          <dt id="cherrypy.lib.sessions.init"><a moz-do-not-send="true"
              class="moz-txt-link-freetext"
href="http://docs.cherrypy.org/en/latest/refman/lib/sessions.html?highlight=sessions.init#cherrypy.lib.sessions.init">http://docs.cherrypy.org/en/latest/refman/lib/sessions.html?highlight=sessions.init#cherrypy.lib.sessions.init</a><br>
          </dt>
          <dt id="cherrypy.lib.sessions.init"><tt class="descclassname">cherrypy.lib.sessions.</tt><tt
              class="descname">init</tt><big>(</big><em>storage_type='ram'</em>,
            <em>path=None</em>, <em>path_header=None</em>, <em>name='session_id'</em>,
            <em>timeout=60</em>, <em>domain=None</em>, <em>secure=False</em>,
            <em>clean_freq=5</em>, <em>persistent=True</em>, <em>httponly=False</em>,
            <em>debug=False</em>, <em>**kwargs</em><big>)</big></dt>
          <dd>
            <p>Initialize session object (using cookies).</p>
            <dl class="docutils">
              <dt>storage_type</dt>
              <dd>One of &#8216;ram&#8217;, &#8216;file&#8217;, &#8216;postgresql&#8217;, &#8216;memcached&#8217;. This
                will be used to look up the corresponding class in
                cherrypy.lib.sessions globals. For example, &#8216;file&#8217; will
                use the FileSession class.</dd>
            </dl>
          </dd>
        </dl>
        <br>
      </div>
    </blockquote>
    <br>
    I am not sure the different between those 2 sessions. I will try to
    figure out<br>
    <br>
    <blockquote cite="mid:530C9DB6.5060501@linux.vnet.ibm.com"
      type="cite">
      <div class="moz-cite-prefix"> <br>
        On 02/25/2014 11:54 AM, Aline Manera wrote:<br>
      </div>
      <blockquote
        cite="mid:1393300441-14159-1-git-send-email-alinefm@linux.vnet.ibm.com"
        type="cite">
        <pre wrap="">From: Aline Manera <a moz-do-not-send="true" class="moz-txt-link-rfc2396E" href="mailto:alinefm@br.ibm.com">&lt;alinefm@br.ibm.com&gt;</a>

There is a readers/writes problem in cherry.sessions.FileSession
implementation which makes it non thread safe.

&gt;From <a moz-do-not-send="true" class="moz-txt-link-freetext" href="https://groups.google.com/forum/#%21topic/cherrypy-users/biitlom41T8">https://groups.google.com/forum/#!topic/cherrypy-users/biitlom41T8</a>
"When the session tool is turned on it hooks the lib.session.save
function onto 'before_finalize' so that the session data is always
re-saved at the end of each request.  For RamSession this is fine
because save just overwrites a dictionary value.  FileSession uses
pickle.dump to write the session data to file and uses pickle.load to
load it. If two requests overlap in just the wrong way then it's
possible that pickle.load gets called halfway through the pickle.dump
which throws an EOFError. More concurrent requests will increase the
chance of this happening."

On Host tab, more concurrent requests happen, specially while creating a
debug report: /host/stats and /tasks/&lt;id&gt;. Because that the problem was
identified there.

To solve this issue, there are 2 options:
1) overwrite cherrypy.session.FileSession._load to fix the
readers/writers and make it thread safe;
or
2) Use RamSession instead of FileSession

As using RamSession makes the application faster because it will not need to
read/write file for each request, this is the best solution in this case.

This patch also uses acquire_lock() and release_lock() for each
read/write session data occurrence.

Signed-off-by: Aline Manera <a moz-do-not-send="true" class="moz-txt-link-rfc2396E" href="mailto:alinefm@br.ibm.com">&lt;alinefm@br.ibm.com&gt;</a>
---
 src/kimchi/auth.py      |   22 +++++++++++++---------
 src/kimchi/config.py.in |    4 ----
 src/kimchi/server.py    |    4 +---
 3 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/src/kimchi/auth.py b/src/kimchi/auth.py
index 94e7eab..fda4e1f 100644
--- a/src/kimchi/auth.py
+++ b/src/kimchi/auth.py
@@ -131,13 +131,13 @@ def check_auth_session():
     A user is considered authenticated if we have an established session open
     for the user.
     """
-    try:
-        if cherrypy.session[USER_ID]:
-            debug("Session authenticated for user %s" %
-                  cherrypy.session[USER_ID])
-            return True
-    except KeyError:
-        pass
+    cherrypy.session.acquire_lock()
+    session = cherrypy.session.get(USER_ID, None)
+    cherrypy.session.release_lock()
+    if session is not None:
+        debug("Session authenticated for user %s" % session)
+        return True
+
     debug("Session not found")
     return False

@@ -188,11 +188,15 @@ def logout():
     cherrypy.lib.sessions.expire()


+
 def has_permission(admin_methods):
+    cherrypy.session.acquire_lock()
+    session = cherrypy.session.get(USER_ID, None)
+    cherrypy.session.release_lock()
+
     return not admin_methods or \
         cherrypy.request.method not in admin_methods or \
-        (cherrypy.request.method in admin_methods and
-            cherrypy.session[USER_SUDO])
+        (cherrypy.request.method in admin_methods and session)


 def kimchiauth(admin_methods=None):
diff --git a/src/kimchi/config.py.in b/src/kimchi/config.py.in
index 32d61c6..92d5b91 100644
--- a/src/kimchi/config.py.in
+++ b/src/kimchi/config.py.in
@@ -36,10 +36,6 @@ from kimchi.xmlutils import xpath_get_text
 DEFAULT_LOG_LEVEL = "debug"


-def get_session_path():
-    return os.path.join(paths.state_dir, 'sessions')
-
-
 def get_object_store():
     return os.path.join(paths.state_dir, 'objectstore')

diff --git a/src/kimchi/server.py b/src/kimchi/server.py
index 6dd0404..ef8e701 100644
--- a/src/kimchi/server.py
+++ b/src/kimchi/server.py
@@ -73,8 +73,7 @@ class Server(object):
               'tools.sessions.name': 'kimchi',
               'tools.sessions.httponly': True,
               'tools.sessions.locking': 'explicit',
-              'tools.sessions.storage_type': 'file',
-              'tools.sessions.storage_path': config.get_session_path(),
+              'tools.sessions.storage_type': 'ram',
               'tools.kimchiauth.on': False},
         '/css': {
             'tools.staticdir.on': True,
@@ -136,7 +135,6 @@ class Server(object):
             os.path.dirname(os.path.abspath(options.error_log)),
             os.path.dirname(os.path.abspath(config.get_object_store())),
             os.path.abspath(config.get_screenshot_path()),
-            os.path.abspath(config.get_session_path()),
             os.path.abspath(config.get_debugreports_path()),
             os.path.abspath(config.get_distros_store())
         ]
</pre>
      </blockquote>
      <br>
      <br>
      <pre class="moz-signature" cols="72">-- 
Thanks and best regards!

Sheldon Feng(&#20911;&#23569;&#21512;)<a moz-do-not-send="true" class="moz-txt-link-rfc2396E" href="mailto:shaohef@linux.vnet.ibm.com">&lt;shaohef@linux.vnet.ibm.com&gt;</a>
IBM Linux Technology Center</pre>
    </blockquote>
    <br>
  </body>
</html>