D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
opt
/
cloudlinux
/
venv
/
lib64
/
python3.11
/
site-packages
/
clcagefslib
/
webisolation
/
Filename :
php.py
back
Copy
#!/opt/cloudlinux/venv/bin/python3 -sbb # -*- coding: utf-8 -*- # # Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2021 All Rights Reserved # # Licensed under CLOUD LINUX LICENSE AGREEMENT # http://cloudlinux.com/docs/LICENCE.TXT # import os import signal import logging import time from pathlib import Path from clcommon.clpwd import drop_privileges import psutil from clcagefslib.webisolation import jail_utils def _term_process(pid, sig): try: os.kill(pid, sig) except OSError as e: logging.error("Failed to terminate process PID %s: %s", pid, str(e)) return False return True def force_process_kill(pids): timeout = time.time() + 5.0 while time.time() < timeout and pids: for pid in list(pids): if not psutil.pid_exists(pid): pids.remove(pid) for pid in list(pids): _term_process(pid, signal.SIGKILL) def _get_website_isolation_docroot(pid: int) -> str | None: """ Checks if the process is in the isolated environment. Returns path to process document root or None """ website_isolation_marker = Path(f"/proc/{pid}/root/var/.cagefs/.cagefs.website") try: return website_isolation_marker.read_text().strip() except (PermissionError, OSError, FileNotFoundError): return None def reload_processes_with_docroots(username: str, filter_by_docroots: list[str]) -> None: """ If filter_by_docroots is not empty - reload only processes with DOCUMENT_ROOT environment variable matching one of the given docroots. Sends SIGTERM/SIGKILL to all matching processes owned by the given username. If filter_by_docroots is empty - reload all processes owned by the given username with DOCUMENT_ROOT set. """ docroots = set([dr for dr in filter_by_docroots if dr]) signaled_pids = set() logging.debug(f"Requested to reload processes for user '{username}' and docroots: {docroots}") # first of all invalidate the existing cache for document_root in docroots: jail_utils.invalidate_ns_cache(username, document_root) # Iterate through all processes and filter by username first for proc in psutil.process_iter(attrs=["pid", "name", "username"]): current_process = proc if current_process.info.get("username") != username: continue try: env = current_process.environ() except psutil.AccessDenied: logging.warning( "Access denied to process PID %s; skipping", current_process.info.get("pid") ) continue # _get_website_isolation_docroot returns document root for processes # which are already isolated, while DOCUMENT_ROOT in env gives us # processes which should be inside isolation (e.g. to kill during site-isolation-enable) document_root = _get_website_isolation_docroot(proc.pid) or env.get("DOCUMENT_ROOT") if docroots and document_root not in docroots: continue pid = current_process.info.get("pid") if pid is None or pid in signaled_pids: continue with drop_privileges(username): logging.info(f"Terminating process PID {pid} with DOCUMENT_ROOT={document_root}") if not _term_process(pid, signal.SIGTERM): continue signaled_pids.add(pid) with drop_privileges(username): force_process_kill(signaled_pids)