You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止iscsiadm执行时向dmesg写日志并输出到所有终端

问题背景

执行sudo iscsiadm -m discovery -t st -p <IP> -l命令时,dmesg内核日志会输出到服务器所有终端,日志格式为[some_num.some_dec] LOG_MESSAGE,会覆盖终端提示符,影响正常系统调试。
该命令由Java应用调用,调用代码如下:

Runtime.getRuntime().exec("/bin/bash", "-c", "sudo iscsiadm -m discovery -t st -p *IP* -l");

已尝试的无效解决方法:

  • 在iscsiadm discovery命令末尾追加> /dev/null 2>&1重定向输出
  • 捕获返回进程的输入流process.getInputStream()和错误流process.getErrorStream()
  • 在Jar包启动命令后追加> /dev/null 2>&1重定向输出
根本原因

上述方案全部无效的核心原因是:这类跨终端打印的日志不是iscsiadm用户态进程产生的stdout/stderr输出,而是内核直接生成的printk日志。默认配置下,优先级高于阈值的内核日志会被直接写入所有活跃虚拟终端的tty设备,完全不经过用户态进程的输出通道,因此常规的用户态输出重定向、流捕获手段无法拦截。

解决方案

可根据实际场景选择对应方案,按影响范围从小到大排序:

1. 单终端临时屏蔽

如果只需要在当前操作的终端屏蔽日志,执行以下命令调整内核控制台打印级别即可:

dmesg -n 1

内核日志级别说明:数值越小优先级越高,1为致命错误,2为严重错误,3为普通错误,4为警告,5为通知,6为常规信息,7为调试信息。系统默认控制台打印级别为4,即优先级≥4的日志都会输出到终端。设置为1后仅致命系统错误会打印到终端,iscsi连接产生的常规信息级日志不会再弹出。
需要恢复默认级别时执行dmesg -n 4即可。

2. Java调用时临时调整级别(推荐)

不需要修改系统全局配置,直接调整Java调用的命令逻辑,在执行iscsiadm操作前临时降低控制台日志级别,操作完成后自动恢复,对其他业务无影响。修改后的bash命令为:

/bin/bash -c "dmesg -n 1; sudo iscsiadm -m discovery -t st -p *IP* -l; dmesg -n 4"

对应Java代码修改为:

Runtime.getRuntime().exec("/bin/bash", "-c", "dmesg -n 1; sudo iscsiadm -m discovery -t st -p *IP* -l; dmesg -n 4");

注意需要保证执行命令的用户拥有调整内核日志级别的权限,sudo执行即可。

3. 全局永久屏蔽

如果需要所有终端永久不再打印非致命内核日志,可修改sysctl配置:

  1. 编辑/etc/sysctl.conf文件,添加或修改以下配置项:
    kernel.printk = 1 4 1 7
    
    四个参数分别对应:控制台日志级别、默认消息日志级别、最小允许控制台日志级别、启动时默认控制台日志级别。
  2. 执行sysctl -p加载配置,立即生效。

4. 仅过滤iscsi相关日志

如果不想调整全局日志级别,只屏蔽iscsi相关的终端日志输出,可通过rsyslog配置规则过滤:

  1. 新建rsyslog配置文件/etc/rsyslog.d/00-block-iscsi.conf
  2. 写入以下规则,阻止iscsi相关日志转发到终端设备:
    :msg, contains, "iscsi" stop
    
  3. 执行systemctl restart rsyslog重启服务生效。

内容的提问来源于stack exchange,提问作者Kris Rice

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 00:03:19