]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
kresctl debug: adjust defaults, documentation
authorOto Šťáva <oto.stava@nic.cz>
Fri, 15 Mar 2024 09:16:16 +0000 (10:16 +0100)
committerAleš Mrázek <ales.mrazek@nic.cz>
Tue, 3 Dec 2024 10:50:01 +0000 (11:50 +0100)
doc/user/manager-client.rst
python/knot_resolver/client/commands/debug.py
python/knot_resolver/client/commands/pids.py

index abeab2c93c1cc01e0e4d03a705d50a22176ff1ea..03a2d9eb84fe196bea5c463b868a5464387cc19d 100644 (file)
@@ -304,3 +304,94 @@ single ``kresctl`` command.
     command is run.
 
     Requires a connection to the management API.
+
+
+.. option:: pids
+
+    Lists the PIDs of the Manager's subprocesses, separated by newlines.
+
+    .. option:: --json
+
+        Makes the output more verbose, in JSON. In addition to the subprocesses'
+        PIDs, it also prints their types and statuses.
+
+    .. option:: [proc_type]
+
+        :default: ``all``
+
+        Optional. The type of process to query. See :ref:`Subprocess types
+        <manager-client-subprocess-types>` for more info.
+
+
+.. option:: debug
+
+    Executes a GDB-compatible debugger and attaches it to the Manager's
+    subprocesses. By default, the debugger is ``gdb`` and the subprocesses are
+    only the ``kresd`` workers.
+
+    .. warning::
+
+        The ``debug`` command is a utility for Knot Resolver developers and is
+        not intended to be used by end-users. Running this command **will** make
+        your resolver unresponsive.
+
+    .. note::
+
+        Modern kernels will prevent debuggers from tracing processes that are
+        not their descendants, which is exactly the scenario that happens with
+        ``kresctl debug``. There are three ways to work around this, listed in
+        the order in which they are preferred in terms of security:
+
+          1. Grant the debugger the ``cap_sys_ptrace`` capability
+             (**recommended**)
+
+              * For ``gdb``, this may be achieved by using the ``setcap``
+                command like so:
+
+                .. code-block:: bash
+
+                    sudo setcap cap_sys_ptrace=eip /usr/bin/gdb
+
+          2. Run the debugger as root
+
+              * You may use the ``--sudo`` option to achieve this
+
+          3. Set ``/proc/sys/kernel/yama/ptrace_scope`` to ``0``
+
+              * This will allow **all** programs in your current session to
+                trace each other. Handle with care!
+
+    .. note::
+
+        This command will only work if executed on the same machine where Knot
+        Resolver is running. Remote debugging is currently not supported.
+
+    .. option:: [proc_type]
+
+        :default: ``kresd``
+
+        Optional. The type of process to debug. See :ref:`Subprocess types
+        <manager-client-subprocess-types>` for more info.
+
+    .. option:: --sudo
+
+        Run the debugger with sudo.
+
+    .. option:: --gdb <command>
+
+        Use a custom GDB executable. This may be a command on ``PATH``, or an
+        absolute path to an executable.
+
+
+.. _manager-client-subprocess-types:
+
+Subprocess types
+----------------
+
+Some of ``kresctl``'s commands (like :option:`pids` and :option:`debug`) take a subprocess
+type value determining which subprocesses will be affected by them. The possible
+values are as follows:
+
+* ``kresd`` -- the worker daemons
+* ``gc`` -- the cache garbage collector
+* ``all`` -- all of the Manager's subprocesses
index 3350fda59fca7a1544838e0a7d3cf488aa3bf45d..cd12db50ddc276c0c6b88b0777d5fec2d209421b 100644 (file)
@@ -27,7 +27,7 @@ class DebugCommand(Command):
     ) -> Tuple[argparse.ArgumentParser, "Type[Command]"]:
         debug = subparser.add_parser(
             "debug",
-            help="Run GDB on the manager's subprocesses - runs with sudo by default to avoid ptrace_scope issues",
+            help="Run GDB on the manager's subprocesses",
         )
         debug.add_argument(
             "proc_type",
@@ -37,14 +37,14 @@ class DebugCommand(Command):
             default="kresd",
         )
         debug.add_argument(
-            "--no-sudo",
+            "--sudo",
             dest="sudo",
-            help="Do not run GDB with sudo (may not work if your ptrace_scope is 1 or higher)",
-            action="store_false",
+            help="Run GDB with sudo",
+            action="store_true",
         )
         debug.add_argument(
             "--gdb",
-            help="GDB command (may be a command on PATH, or an absolute path)",
+            help="Custom GDB executable (may be a command on PATH, or an absolute path)",
             type=str,
             default=None,
         )
index 2a7a5e85f1339f00dbfdc71b953df4f0f71f04cc..a1ab5f8c8d67defb57e3c93e8a3dbb6ca88107d8 100644 (file)
@@ -13,7 +13,7 @@ PROCESSES_TYPE = Iterable
 class PidsCommand(Command):
     def __init__(self, namespace: argparse.Namespace) -> None:
         self.proc_type: Optional[str] = namespace.proc_type
-        self.verbose: int = namespace.verbose
+        self.json: int = namespace.json
 
         super().__init__(namespace)
 
@@ -21,7 +21,7 @@ class PidsCommand(Command):
     def register_args_subparser(
         subparser: "argparse._SubParsersAction[argparse.ArgumentParser]",
     ) -> Tuple[argparse.ArgumentParser, "Type[Command]"]:
-        pids = subparser.add_parser("pids", help="list the PIDs of kresd manager subprocesses")
+        pids = subparser.add_parser("pids", help="List the PIDs of the Manager's subprocesses")
         pids.add_argument(
             "proc_type",
             help="Optional, the type of process to query. May be 'kresd', 'gc', or 'all' (default).",
@@ -29,11 +29,10 @@ class PidsCommand(Command):
             default="all",
         )
         pids.add_argument(
-            "-v",
-            "--verbose",
-            help="Optional, makes the output more verbose, in a machine-readable format.",
-            action="count",
-            default=0,
+            "--json",
+            help="Optional, makes the output more verbose, in JSON.",
+            action="store_true",
+            default=False,
         )
         return pids, PidsCommand
 
@@ -47,12 +46,11 @@ class PidsCommand(Command):
         if response.status == 200:
             processes = json.loads(response.body)
             if isinstance(processes, PROCESSES_TYPE):
-                if self.verbose < 1:
-                    for p in processes:
-                        print(p["pid"])
+                if self.json:
+                    print(json.dumps(processes, indent=2))
                 else:
                     for p in processes:
-                        print(p)
+                        print(p["pid"])
 
             else:
                 print(