前情提要 最近更新了 arch 在开机 Loading inital ramdisk 后会 kernel panic - #4,来自 依云
最近花了不少时间重装系统和恢复开发环境,原本一切正常,直到我尝试使用 Navicat 提供的 Appimage 连接达梦数据库时开始旧疾复发。为了连接达梦数据库 Navicat 需要安装一个 odbc 驱动。
在达梦官网的驱动包里有一个脚本 install_obdc_linux.sh 我还没完全看懂这个的内容,使用 sudo 执行后会在 /opt、/etc 下创建一些目录并写入内容。
安装完驱动后最重启 navicat 可以正常使用并连接数据库,但是一段时间后 navicat 将无法打开,并且会提示 segment fault,然后在关机时有一个叫 User Manager 的服务会卡 1min 左右,接着就是 Kernel Panic 了。
目前我还没搞清楚怎么处理,我手动把 /opt 和 /etc 下面的一些内容删除过后重启正常了,看看有没有哪位大佬知道怎么回事
# install_odbc_linux.sh
#!/bin/sh
# ============================================================================
# Dameng ODBC Driver Installer for Linux (System & Flatpak)
# ============================================================================
# Description: This script installs the Dameng ODBC driver for both standard
# system use and for sandboxed Flatpak applications.
# ============================================================================
# --- Configuration Constants ---
LIB_NAME="libdodbc.so"
# System-wide installation config
SYSTEM_DEST_PATH_DEFAULT="/opt/dameng_odbc"
SYSTEM_CONF_FILE="/etc/ld.so.conf.d/dameng_odbc.conf"
SYSTEM_DRIVER_SECTION="DM8 ODBC DRIVER"
ENV_VAR_FILE="/etc/profile.d/dm_home.sh"
# Flatpak-specific installation config
FLATPAK_DEST_PATH="$HOME/.config/navicat/ODBC/dameng"
FLATPAK_CONF_FILE="/etc/ld.so.conf.d/dameng_odbc_flatpak.conf"
FLATPAK_DRIVER_SECTION="DM8 ODBC DRIVER FLATPAK"
ODBC_INST_FILE="/etc/odbcinst.ini"
# --- Color Definitions ---
ORANGE='\033[0;33m'
NC='\033[0m' # No Color
# --- Help Message ---
show_help() {
echo "Usage: $0"
echo "Installs the Dameng ODBC driver for both system and Flatpak use."
echo
echo "This script must be run from the directory containing the Dameng"
echo "ODBC driver files (e.g., libdodbc.so)."
echo
echo "Options:"
echo " -h, --help Show this help message"
exit 0
}
# --- Argument Parser ---
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
show_help
fi
# ============================================================================
# User Confirmation
# ============================================================================
printf "\nThis script installs the Dameng ODBC driver for both standard system use and for sandboxed Flatpak applications.\n"
printf "${ORANGE}It will use 'sudo' to modify system configuration files in '/etc'.${NC}\n"
printf "You will be prompted for your password to proceed.\n\n"
printf "Press [Enter] to continue or Ctrl+C to cancel... "
read -r _ # Wait for user input, store it in a throwaway variable
echo
echo
# ============================================================================
# Pre-run Checks
# ============================================================================
# Check for required tools
REQUIRED_TOOLS="grep awk sed sudo ldconfig cp mkdir dirname chmod tee"
MISSING_TOOLS=""
for tool in $REQUIRED_TOOLS; do
if ! command -v "$tool" >/dev/null 2>&1; then
MISSING_TOOLS="$MISSING_TOOLS $tool"
fi
done
if [ -n "$MISSING_TOOLS" ]; then
echo "ERROR: Missing required tools:"
for t in $MISSING_TOOLS; do
echo " - $t"
done
exit 1
fi
# --- Main Execution ---
# Get the directory where the script and driver files are located
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
if [ ! -f "${SCRIPT_DIR}/${LIB_NAME}" ]; then
echo "ERROR: The required driver file '${LIB_NAME}' was not found in the script's directory."
echo "Please run this script from the same folder where the Dameng driver files are located."
exit 1
fi
# ============================================================================
# Phase 1: File Installation
# ============================================================================
echo "--- Phase 1: File Installation ---"
echo
echo "First, for the main system-wide installation:"
printf "Enter path (or press Enter to use default: %s): " "$SYSTEM_DEST_PATH_DEFAULT"
read -r USER_PATH
# Set system destination path to default if user input is empty
if [ -z "$USER_PATH" ]; then
SYSTEM_DEST_PATH="$SYSTEM_DEST_PATH_DEFAULT"
else
SYSTEM_DEST_PATH="$USER_PATH"
fi
# --- System Installation ---
echo "Installing system driver to: ${SYSTEM_DEST_PATH} (requires sudo)..."
sudo mkdir -p "$SYSTEM_DEST_PATH"
if [ $? -ne 0 ]; then
echo "ERROR: Failed to create system destination directory."
exit 1
fi
sudo find "$SCRIPT_DIR" -mindepth 1 -maxdepth 1 -not -name "$(basename "$0")" -exec cp -r {} "$SYSTEM_DEST_PATH/" \;
if [ $? -ne 0 ]; then
echo "ERROR: Failed to copy files to the system destination."
exit 1
fi
echo "System driver files copied successfully."
echo
# --- Flatpak Installation ---
echo "Installing Flatpak driver to: ${FLATPAK_DEST_PATH}..."
mkdir -p "$FLATPAK_DEST_PATH"
if [ $? -ne 0 ]; then
echo "ERROR: Failed to create Flatpak destination directory."
exit 1
fi
find "$SCRIPT_DIR" -mindepth 1 -maxdepth 1 -not -name "$(basename "$0")" -exec cp -r {} "$FLATPAK_DEST_PATH/" \;
if [ $? -ne 0 ]; then
echo "ERROR: Failed to copy files to the Flatpak destination."
exit 1
fi
echo "Flatpak driver files copied successfully."
echo
# ============================================================================
# Phase 2: System Configuration
# ============================================================================
echo "--- Phase 2: System Configuration (requires sudo) ---"
echo
# --- Configure System Driver ---
echo "Configuring the system-wide driver..."
echo "$SYSTEM_DEST_PATH" | sudo tee "$SYSTEM_CONF_FILE" >/dev/null
if sudo grep -q "^\\[${SYSTEM_DRIVER_SECTION}\\]" "$ODBC_INST_FILE" 2>/dev/null; then
echo "Replacing previous '${SYSTEM_DRIVER_SECTION}' entry..."
TEMP_FILE=$(mktemp)
# Corrected awk command to reliably delete the entire section
sudo awk -v section="[${SYSTEM_DRIVER_SECTION}]" '
$0 == section { in_section = 1; next }
$0 ~ /^\[/ { in_section = 0 }
!in_section { print }
' "$ODBC_INST_FILE" > "$TEMP_FILE" && sudo mv "$TEMP_FILE" "$ODBC_INST_FILE"
fi
{
printf "\n[%s]\n" "$SYSTEM_DRIVER_SECTION"
printf "Description = Dameng ODBC Driver\n"
printf "Driver = %s/%s\n" "$SYSTEM_DEST_PATH" "$LIB_NAME"
} | sudo tee -a "$ODBC_INST_FILE" >/dev/null
echo "System driver configured."
echo
# --- Configure Flatpak Driver ---
echo "Configuring the Flatpak-specific driver..."
echo "$FLATPAK_DEST_PATH" | sudo tee "$FLATPAK_CONF_FILE" >/dev/null
if sudo grep -q "^\\[${FLATPAK_DRIVER_SECTION}\\]" "$ODBC_INST_FILE" 2>/dev/null; then
echo "Replacing previous '${FLATPAK_DRIVER_SECTION}' entry..."
TEMP_FILE=$(mktemp)
# Corrected awk command to reliably delete the entire section
sudo awk -v section="[${FLATPAK_DRIVER_SECTION}]" '
$0 == section { in_section = 1; next }
$0 ~ /^\[/ { in_section = 0 }
!in_section { print }
' "$ODBC_INST_FILE" > "$TEMP_FILE" && sudo mv "$TEMP_FILE" "$ODBC_INST_FILE"
fi
{
printf "\n[%s]\n" "$FLATPAK_DRIVER_SECTION"
printf "Description = Dameng ODBC Driver (Flatpak)\n"
printf "Driver = %s/%s\n" "$FLATPAK_DEST_PATH" "$LIB_NAME"
} | sudo tee -a "$ODBC_INST_FILE" >/dev/null
echo "Flatpak driver configured."
echo
# --- Finalize Linker ---
echo "Updating linker cache..."
sudo ldconfig
echo "Linker cache updated."
echo
# ============================================================================
# Phase 2a: Set System Environment Variable
# ============================================================================
echo "--- Phase 2a: Setting DM_HOME Environment Variable for System Install ---"
echo
# First, check if the variable is already set in the current environment
if [ -n "$DM_HOME" ]; then
DM_HOME_ACTION="existed"
EXISTING_VALUE="$DM_HOME"
echo "Environment variable 'DM_HOME' is already set in the current session."
echo "Value: $EXISTING_VALUE"
echo "Skipping this step."
else
# If not in current session, check persistent system-wide profile files
EXISTING_SETTING=$(grep -r "^export DM_HOME=" /etc/profile.d/ /etc/environment 2>/dev/null | head -n 1)
if [ -n "$EXISTING_SETTING" ]; then
DM_HOME_ACTION="existed"
EXISTING_VALUE=$(echo "$EXISTING_SETTING" | cut -d'=' -f2)
echo "System environment variable 'DM_HOME' appears to be already set in configuration files."
echo "Found setting: $EXISTING_VALUE"
echo "Skipping this step to avoid conflicts."
else
# If it doesn't exist anywhere, set it for the system-wide path.
echo "Setting system environment variable 'DM_HOME' to '${SYSTEM_DEST_PATH}'..."
# Create a script in /etc/profile.d to set the variable for all users on login
echo "export DM_HOME=\"${SYSTEM_DEST_PATH}\"" | sudo tee "${ENV_VAR_FILE}" >/dev/null
sudo chmod +x "${ENV_VAR_FILE}"
if [ $? -eq 0 ]; then
DM_HOME_ACTION="set"
echo "Successfully created ${ENV_VAR_FILE}."
echo "The 'DM_HOME' variable will be available in new terminal sessions or after a reboot."
else
DM_HOME_ACTION="failed"
echo "ERROR: Failed to create environment variable file."
fi
fi
fi
echo
# ============================================================================
# Phase 3: Installation Summary
# ============================================================================
echo "--- Phase 3: Installation Summary ---"
echo
echo "==================================================="
echo " Dameng ODBC Driver Installation Complete"
echo "==================================================="
echo
echo " --- System Installation ---"
printf " %-22s %s\n" "Driver Name:" "$SYSTEM_DRIVER_SECTION"
printf " %-22s %s\n" "Installed To:" "$SYSTEM_DEST_PATH"
if [ "$DM_HOME_ACTION" = "set" ]; then
printf " %-22s %s\n" "Environment Variable:" "DM_HOME set to ${SYSTEM_DEST_PATH}"
elif [ "$DM_HOME_ACTION" = "existed" ]; then
printf " %-22s %s\n" "Environment Variable:" "DM_HOME already exists (Value: ${EXISTING_VALUE})"
fi
echo
echo " --- Flatpak Installation ---"
printf " %-22s %s\n" "Driver Name:" "$FLATPAK_DRIVER_SECTION"
printf " %-22s %s\n" "Installed To:" "$FLATPAK_DEST_PATH"
echo
echo " The drivers are now configured for use."
echo "==================================================="
echo