This is an automated email from the ASF dual-hosted git repository.

dataroaring pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new e516726d7ef [opt](docker compose) Support get core dump file from 
docker compose (#54913)
e516726d7ef is described below

commit e516726d7ef24645e0a75cdad0299c30ced38409
Author: deardeng <[email protected]>
AuthorDate: Tue Aug 19 09:39:36 2025 +0800

    [opt](docker compose) Support get core dump file from docker compose 
(#54913)
---
 docker/runtime/doris-compose/Readme.md             | 75 ++++++++++++++++++++++
 docker/runtime/doris-compose/cluster.py            | 23 ++++++-
 docker/runtime/doris-compose/command.py            |  3 +-
 .../runtime/doris-compose/resource/entrypoint.sh   | 19 ++++++
 4 files changed, 117 insertions(+), 3 deletions(-)

diff --git a/docker/runtime/doris-compose/Readme.md 
b/docker/runtime/doris-compose/Readme.md
index f304069c3c1..c4b60460e49 100644
--- a/docker/runtime/doris-compose/Readme.md
+++ b/docker/runtime/doris-compose/Readme.md
@@ -213,6 +213,81 @@ steps:
 
 Each cluster has logs in Docker in 
'/tmp/doris/{cluster-name}/{node-xxx}/log/'. For each node, doris compose will 
also print log in '/tmp/doris/{cluster-name}/{node-xxx}/log/health.out'
 
+### Core Dump
+
+Doris Compose supports core dump generation for debugging purposes. When a 
process crashes, it will generate a core dump file that can be analyzed with 
tools like gdb.
+
+#### Core Dump Location
+
+Core dump files are generated in the following locations:
+
+- **Host System**: `/tmp/doris/{cluster-name}/{node-xxx}/core_dump/`
+- **Container**: `/opt/apache-doris/core_dump/`
+
+The core dump files follow the pattern: `core.{executable}.{pid}.{timestamp}`
+
+For example:
+```
+/tmp/doris/my-cluster/be-1/core_dump/core.doris_be.12345.1755418335
+```
+
+#### Core Pattern Configuration
+
+The system uses the core pattern from `/proc/sys/kernel/core_pattern` on the 
host system. The default pattern is:
+```
+/opt/apache-doris/core_dump/core.%e.%p.%t
+```
+
+Where:
+- `%e`: executable name
+- `%p`: process ID
+- `%t`: timestamp
+
+#### Core Dump Settings
+
+Doris Compose automatically configures the following settings for core dump 
generation:
+
+1. **Container Settings**:
+   - `ulimits.core = -1` (unlimited core file size)
+   - `cap_add: ["SYS_ADMIN"]` (required capabilities)
+   - `privileged: true` (privileged mode)
+
+2. **Directory Permissions**:
+   - Core dump directory is created with 777 permissions
+   - Ownership is set to the host user for non-root containers
+
+3. **Non-Root User Support**:
+   - Core dump directory permissions are automatically configured
+   - Works with both root and non-root user containers
+
+#### Troubleshooting
+
+If core dumps are not being generated:
+
+1. **Check ulimit settings**:
+   ```bash
+   ulimit -c
+   # Should return "unlimited" or a positive number
+   ```
+
+2. **Check directory permissions**:
+   ```bash
+   ls -la /tmp/doris/{cluster-name}/{node-xxx}/core_dump/
+   # Should show 777 permissions
+   ```
+
+3. **Check core pattern**:
+   ```bash
+   cat /proc/sys/kernel/core_pattern
+   # Should show the expected pattern
+   ```
+
+4. **Check container logs**:
+   ```bash
+   docker logs {container-name}
+   # Look for core dump related messages
+   ```
+
 ### Up cluster using non-detach mode
 
 ```shell
diff --git a/docker/runtime/doris-compose/cluster.py 
b/docker/runtime/doris-compose/cluster.py
index 8d4d65097e9..cf63f403240 100644
--- a/docker/runtime/doris-compose/cluster.py
+++ b/docker/runtime/doris-compose/cluster.py
@@ -371,6 +371,14 @@ class Node(object):
         return utils.with_doris_prefix("{}-{}".format(self.cluster.name,
                                                       self.get_name()))
 
+    def get_system_core_pattern(self):
+        """Get system core pattern from /proc/sys/kernel/core_pattern"""
+        try:
+            with open("/proc/sys/kernel/core_pattern", "r") as f:
+                return f.read().strip()
+        except:
+            return "core"
+
     def docker_env(self):
         enable_coverage = self.cluster.coverage_dir
 
@@ -433,7 +441,19 @@ class Node(object):
         raise Exception("No implemented")
 
     def compose(self):
+        # Get system core pattern to determine core dump directory
+        core_pattern = self.get_system_core_pattern()
+
+        # Extract directory from core pattern if it's an absolute path
+        core_dump_dir = "/opt/apache-doris/core_dump"  # default
+        if core_pattern.startswith("/"):
+            # Extract directory part (everything before the filename)
+            core_dump_dir = os.path.dirname(core_pattern)
+
         volumes = [
+            "{}:{}".format(os.path.join(self.get_path(), "core_dump"),
+                           core_dump_dir)
+        ] + [
             "{}:{}/{}".format(os.path.join(self.get_path(), sub_dir),
                               self.docker_home_dir(), sub_dir)
             for sub_dir in self.expose_sub_dirs()
@@ -452,7 +472,8 @@ class Node(object):
                                                    DOCKER_DORIS_PATH))
 
         content = {
-            "cap_add": ["SYS_PTRACE"],
+            "cap_add": ["SYS_ADMIN"],
+            "privileged": "true",
             "container_name": self.service_name(),
             "environment": self.docker_env(),
             "image": self.get_image(),
diff --git a/docker/runtime/doris-compose/command.py 
b/docker/runtime/doris-compose/command.py
index 56ef98a89a8..3aff8a4b3db 100644
--- a/docker/runtime/doris-compose/command.py
+++ b/docker/runtime/doris-compose/command.py
@@ -1258,8 +1258,7 @@ class ListCommand(Command):
                 if services is None:
                     return COMPOSE_BAD, {}
                 return COMPOSE_GOOD, {
-                    service:
-                    ComposeService(
+                    service: ComposeService(
                         service, ip_for_host_mode if ip_for_host_mode else
                         list(service_conf["networks"].values())[0]
                         ["ipv4_address"], service_conf["image"])
diff --git a/docker/runtime/doris-compose/resource/entrypoint.sh 
b/docker/runtime/doris-compose/resource/entrypoint.sh
index a3cdaaae8f1..0446004d9c2 100644
--- a/docker/runtime/doris-compose/resource/entrypoint.sh
+++ b/docker/runtime/doris-compose/resource/entrypoint.sh
@@ -58,6 +58,25 @@ create_host_user() {
 
 create_host_user
 
+# Setup core dump directory permissions for non-root users
+setup_core_dump() {
+    # Set fs.suid_dumpable to allow core dumps from setuid programs
+    echo 2 >/proc/sys/fs/suid_dumpable
+    # Set core pattern to save core dumps in the mounted directory
+    echo "/opt/apache-doris/core_dump/core-%e-%p-%t" 
>/proc/sys/kernel/core_pattern
+    if [ ! -z ${HOST_USER} ]; then
+        # Create core dump directory if it doesn't exist
+        mkdir -p /opt/apache-doris/core_dump
+        # Set permissions to allow core dumps from non-root users
+        chmod 777 /opt/apache-doris/core_dump
+        # Set ownership to the host user
+        chown ${HOST_USER}:${HOST_USER} /opt/apache-doris/core_dump
+        health_log "setup core dump directory for user ${HOST_USER}"
+    fi
+}
+
+setup_core_dump
+
 if command -v gosu 2>&1 >/dev/null; then
     if [ -f ${LOG_FILE} ]; then
         chown ${RUN_USER}:${RUN_USER} ${LOG_FILE}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to