[Kimchi-devel] [kimchi-devel][PATCH 6/7] Work around eventfd leak using multiprocessing
Aline Manera
alinefm at linux.vnet.ibm.com
Thu Jan 22 17:50:09 UTC 2015
Reviewed-by: Aline Manera <alinefm at linux.vnet.ibm.com>
On 20/01/2015 06:45, lvroyce at linux.vnet.ibm.com wrote:
> From: Royce Lv <lvroyce at linux.vnet.ibm.com>
>
> When accessing kimchi server url with authentication every time(no session),
> kimchi server will deny service after about 1000 requests.
> "GET /storagepools/default/storagevolumes/ HTTP/1.0" 200 563 "" ""
> Failed to run command: id -Gn royce. [Errno 24] Too many open files
> After tracking with 'lsof', "eventfd" handler leak for kimchi server.
>
> This is because when using pam_start() to generate a pam file handler,
> it needs to be closed by pam_end().
> Unfortunately, PyPAM module only export start() function without end().
>
> This patch workaround leak by putting PAM authentication in
> a sub process, so that when it finishes execution,
> its opening file handler will be closed by system automatically.
>
> REF:
> http://linux.die.net/man/3/pam_end
> http://stackoverflow.com/questions/5125245/how-to-authenticate-a-user-using-pam
>
> Signed-off-by: Royce Lv <lvroyce at linux.vnet.ibm.com>
> ---
> src/kimchi/auth.py | 65 +++++++++++++++++++++++++++++++-----------------------
> 1 file changed, 37 insertions(+), 28 deletions(-)
>
> diff --git a/src/kimchi/auth.py b/src/kimchi/auth.py
> index 22c5c81..8cdbe76 100644
> --- a/src/kimchi/auth.py
> +++ b/src/kimchi/auth.py
> @@ -145,35 +145,44 @@ class PAMUser(User):
> @staticmethod
> def authenticate(username, password, service="passwd"):
> '''Returns True if authenticate is OK via PAM.'''
> - def _pam_conv(auth, query_list, userData=None):
> - resp = []
> - for i in range(len(query_list)):
> - query, qtype = query_list[i]
> - if qtype == PAM.PAM_PROMPT_ECHO_ON:
> - resp.append((username, 0))
> - elif qtype == PAM.PAM_PROMPT_ECHO_OFF:
> - resp.append((password, 0))
> - elif qtype == PAM.PAM_PROMPT_ERROR_MSG:
> - cherrypy.log.error_log.error(
> - "PAM authenticate prompt error: %s" % query)
> - resp.append(('', 0))
> - elif qtype == PAM.PAM_PROMPT_TEXT_INFO:
> - resp.append(('', 0))
> - else:
> - return None
> - return resp
> -
> - auth = PAM.pam()
> - auth.start(service)
> - auth.set_item(PAM.PAM_USER, username)
> - auth.set_item(PAM.PAM_CONV, _pam_conv)
> - try:
> - auth.authenticate()
> - except PAM.error, (resp, code):
> - msg_args = {'username': username, 'code': code}
> - raise OperationFailed("KCHAUTH0001E", msg_args)
> + def _auth(result):
> + def _pam_conv(auth, query_list, userData=None):
> + resp = []
> + for i in range(len(query_list)):
> + query, qtype = query_list[i]
> + if qtype == PAM.PAM_PROMPT_ECHO_ON:
> + resp.append((username, 0))
> + elif qtype == PAM.PAM_PROMPT_ECHO_OFF:
> + resp.append((password, 0))
> + elif qtype == PAM.PAM_PROMPT_ERROR_MSG:
> + cherrypy.log.error_log.error(
> + "PAM authenticate prompt error: %s" % query)
> + resp.append(('', 0))
> + elif qtype == PAM.PAM_PROMPT_TEXT_INFO:
> + resp.append(('', 0))
> + else:
> + return None
> + return resp
>
> - return True
> + result.value = False
> + auth = PAM.pam()
> + auth.start(service)
> + auth.set_item(PAM.PAM_USER, username)
> + auth.set_item(PAM.PAM_CONV, _pam_conv)
> + try:
> + auth.authenticate()
> + except PAM.error, (resp, code):
> + msg_args = {'username': username, 'code': code}
> + raise OperationFailed("KCHAUTH0001E", msg_args)
> +
> + result.value = True
> +
> + result = multiprocessing.Value('i', 0, lock=False)
> + p = multiprocessing.Process(target=_auth, args=(result, ))
> + p.start()
> + p.join()
> +
> + return result.value
>
>
> class LDAPUser(User):
More information about the Kimchi-devel
mailing list