本文记录在 CentOS 7 环境下编译安装 Transmission 2.94, 并通过修改源码添加 跳过校验 (Skip Hash Check) 功能的相关步骤。适用于 已有完整数据 需要快速做种, 或迁移数据后避免长时间 Hash 校验的场景。
安装编译环境及依赖
安装编译 Transmission 所需的基础环境及依赖库, 包括 libevent、curl、zlib 与 OpenSSL 等组件
yum install -y automake libtool libcurl-devel libevent-devel zlib-devel openssl11 openssl11-devel intltool
下载 Transmission 源码
Transmission 官方发布仓库。下载并解压 Transmission 2.94 源码, 后续修改与编译操作均在源码目录中进行
wget https://github.com/transmission/transmission-releases/raw/master/transmission-2.94.tar.xz
tar xf transmission-2.94.tar.xz
cd transmission-2.94
使用 OpenSSL 1.1
CentOS 7 默认 OpenSSL 版本较低, Transmission 2.94 编译时需手动指定 OpenSSL 1.1 的头文件与库文件路径
export OPENSSL_CFLAGS=$(pkg-config --cflags openssl11)
export OPENSSL_LIBS=$(pkg-config --libs openssl11)
添加跳过校验检查功能
通过修改 Transmission 源码, 可在添加种子后选择跳过 Hash 校验, 适用于 本地已存在完整数据、迁移做种数据或大体积种子快速做种等场景。
手动修改源码
参考 transmission-2.92_skiphashcheck 项目。该修改方案原用于 Transmission 2.92, 经测试同样适用于 Transmission 2.94
编辑 libtransmission/rpcimpl.c 文件, 在 388 行位置调用 skiphash() 函数
386
387 assert (idle_data == NULL);
388
389+ skiphash();
390 torrents = getTorrents (session, args_in, &torrentCount);
391 for (i=0; i<torrentCount; ++i)
392 {
编辑 libtransmission/verify.c 文件, 在 41 行位置新增全局变量和函数定义
39 MSEC_TO_SLEEP_PER_SECOND_DURING_VERIFY = 100
40 };
41
42+static bool skiphashcheck=false;
43+void skiphash(){
44+ skiphashcheck=true;
45+}
46+
47 static bool
48 verifyTorrent (tr_torrent * tor, bool * stopFlag)
49 {
修改约 81 行附近代码, 在文件打开判断前增加 !skiphashcheck && 条件
78 hadPiece = tr_torrentPieceIsComplete (tor, pieceIndex);
79
80 /* if we're starting a new file... */
81- if (filePos == 0 && fd == TR_BAD_SYS_FILE && fileIndex != prevFileIndex)
82+ if (!skiphashcheck && filePos == 0 && fd == TR_BAD_SYS_FILE && fileIndex != prevFileIndex)
83 {
84 char * filename = tr_torrentFindFile (tor, fileIndex);
85 fd = filename == NULL ? TR_BAD_SYS_FILE : tr_sys_file_open (filename,
修改约 100 行附近代码, 在文件读取时增加 !skiphashcheck && 条件
97 if (fd != TR_BAD_SYS_FILE)
98 {
99 uint64_t numRead;
100- if (tr_sys_file_read_at (fd, buffer, bytesThisPass, filePos, &numRead, NULL) && numRead > 0)
101+ if (!skiphashcheck && tr_sys_file_read_at (fd, buffer, bytesThisPass, filePos, &numRead, NULL) && numRead > 0)
102 {
103 bytesThisPass = numRead;
104 tr_sha1_update (sha, buffer, bytesThisPass);
修改约 124 行附近代码, 使校验逻辑直接返回成功
121 uint8_t hash[SHA_DIGEST_LENGTH];
122
123 tr_sha1_final (sha, hash);
124- hasPiece = !memcmp (hash, tor->info.pieces[pieceIndex].hash, SHA_DIGEST_LENGTH);
125+ hasPiece = skiphashcheck || !memcmp (hash, tor->info.pieces[pieceIndex].hash, SHA_DIGEST_LENGTH);
126
127 if (hasPiece || hadPiece)
128 {
最后在约 162 行位置增加日志输出及状态重置
159 }
160 }
161
162+ if(skiphashcheck){
163+ skiphashcheck=false;
164+ tr_logAddTorInfo (tor, "%s", _("skip hash check"));
165+ }
166 /* cleanup */
167 if (fd != TR_BAD_SYS_FILE)
168 tr_sys_file_close (fd, NULL);
修改完成后, 可参考下图查看完整差异

使用 Patch 一键修改源码
如果不希望手动修改源码, 可以直接应用现成的 Patch 文件
# 下载 Patch
wget https://github.com/superlukia/transmission-2.92_skiphashcheck/commit/56e327d1dacb5b3453954b76a6d0edd30edb7a34.patch
# 使用 patch 命令应用
patch -p 1 < 56e327d1dacb5b3453954b76a6d0edd30edb7a34.patch
# 或者使用 Git 的 Patch 应用方式
git apply 56e327d1dacb5b3453954b76a6d0edd30edb7a34.patch
应用完成后即可继续编译 Transmission
编译安装 Transmission
Transmission 2.94 依赖较新的 GCC 版本进行编译, 而 CentOS 7 默认提供的 GCC 4.8 版本过低, 因此需要先安装 Software Collections (SCL) 中的 GCC 9 编译工具链
安装 GCC 9
yum install epel-release centos-release-scl -y
yum install devtoolset-9-gcc* -y
使用 GCC 9 生成编译配置并编译源码
scl enable devtoolset-9 "./autogen.sh --prefix=/usr"
scl enable devtoolset-9 "make -j"
make install
编译完成后, 可通过以下命令确认版本信息
transmission-daemon --version
使用方式
完成编译安装后, 即可使用跳过校验功能
在 Transmission Web 界面添加种子后, 当任务进入校验状态时, 右键点击对应种子, 选择
Ask tracker for more peers
获取更多 Peer
此时 Transmission 会跳过 Hash 校验过程, 直接将种子标记为已完成并开始做种
该功能 仅适用于本地已存在完整数据 的场景, 例如 迁移做种数据、重装系统后恢复种子 或 快速重新做种 等
创建 systemd 服务
Transmission 编译安装完成后, 可以创建 systemd 服务实现开机自启动
由于本文编译过程中 未启用 libsystemd-devel 支持, 因此 service 文件建议使用 Type=simple 而不是 Type=notify, 否则可能出现 systemctl start transmission 后服务长时间处于 activating 状态的问题。
编辑服务文件
vim /etc/systemd/system/transmission.service
写入以下内容
[Unit]
Description=Transmission Service
After=network.target
[Service]
User=acesheep # 修改为实际运行 Transmission 的用户
Group=acesheep # 修改为实际运行 Transmission 的用户
Type=simple
ExecStart=/usr/bin/transmission-daemon --log-error -f
ExecStop=/bin/kill -s TERM $MAINPID
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=666666
[Install]
WantedBy=multi-user.target
加载并启动服务
systemctl daemon-reload
systemctl start transmission
systemctl enable transmission
systemctl status transmission
# Transmission 在不中断下载任务的情况下重新加载配置
# - 重新加载配置文件
# - 重新打开日志文件
# - 不会中断当前下载和做种任务
# - 不会退出进程
systemctl reload transmission
配置防火墙 firewalld
Transmission 默认需要监听 BT 通信端口。如果系统启用了 firewalld, 则需要放行对应端口, 否则可能影响 Peer 连接数量以及下载、上传效率
本文以 52333 端口为例, 通过自定义 Firewalld Service 的方式放行 Transmission 使用的 TCP 和 UDP 端口
创建服务配置文件
vim /usr/lib/firewalld/services/transmission-client.xml
写入以下内容
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>Transmission</short>
<description>Transmission is a lightweight BitTorrent client.</description>
<port protocol="tcp" port="52333"/>
<port protocol="udp" port="52333"/>
</service>
加载并启用防火墙规则
firewall-cmd --add-service=transmission-client --permanent
firewall-cmd --reload
验证规则是否生效。如果输出结果中包含 transmission-client 则表示防火墙规则已成功加载
firewall-cmd --list-services
如果 Transmission 使用的不是 52333 端口, 请根据实际配置修改 XML 文件中的端口号, 然后重新加载 firewalld 配置
设置文件打开数量
当 Transmission 管理大量种子或建立大量 Peer 连接时, 系统默认的文件描述符 (File Descriptor) 限制可能不足, 从而导致出现 Too many open files 错误。因此建议适当提高系统和用户的文件打开数量限制
首先查看当前系统和用户的限制值
cat /proc/sys/fs/file-max
ulimit -Hn
ulimit -Sn
其中
file-max: 系统级最大文件句柄数量ulimit -Hn: 当前用户硬限制 (Hard Limit)ulimit -Sn: 当前用户软限制 (Soft Limit)
编辑 limits.conf 配置文件
vim /etc/security/limits.conf
添加以下内容
root hard nofile 1048573
root soft nofile 1048573
acesheep hard nofile 1048573
acesheep soft nofile 1048573
说明
root为系统管理员账户acesheep为运行 Transmission 的用户, 请根据实际情况修改hard为硬限制soft为软限制nofile表示允许打开的最大文件数量
修改完成后, 重新登录用户会话或重启系统使配置生效
验证当前限制
ulimit -a
如果 Transmission 通过 systemd 启动, 还建议在 service 文件中增加
LimitNOFILE=666666
这是因为 systemd 启动的服务不一定会继承 limits.conf 中配置的文件描述符限制。对于大量种子、高并发连接或长期做种的场景, 建议同时配置 limits.conf 和 LimitNOFILE, 以确保 Transmission 能获得足够的文件句柄资源
原文