红米 5A 刷欧洲版 MIUI 记录

老年人的第一次刷机。

最近把红米备机拿出来用了,升到了 ADUI 10,感觉还不错,但是广告实在太多。想起来当年被卡 15 天解 BL 锁的限制早过了很久了,就想着把这破系统刷了吧。

查了一圈发现 MIUI EU 版是相对干净的系统,可以在这里取得。

准备工作

解锁 Bootloader
MIUI EU 版刷机包
Android Debug Bridge
第三方 Recovery TWRP
Root 包 Magisk

刷机步骤

  1. 解锁 Bootloader
    1. 进入“设置 -> 开发者选项 -> 设备解锁状态”中绑定账号和设备;
    2. 手动进入 Fastboot 模式(关机后,同时按住开机键和音量下键);
    3. 通过USB连接手机,点击 “解锁”按钮;
  2. 刷入 TWRP
    1. 在 Bootloader 模式下,运行 fastboot flash recovery <twrp_image>刷入 TWRP
    2. fastboot reboot 重启设备,注意此时需要立即按下音量上 + 电源以进入 Recovery 模式,否则 MIUI 会覆盖刷入的自定义 Revocery
  3. Recovery 成功刷入设备后,将手机关机,在关机状态下按住电源键和音量上键,进入 Recovery 模式,滑动 Swipe to Allow Modifications 进入主菜单。点击 Wipe,点击 Format Data,输入 yes 完成格式化,返回上一菜单,点击 Advanced Wipe,选择 Dalvik,Cache,System,Data 和 Internal Storage 分区,并滑动 Swipe to Wipe 进行擦除,然后返回 Recovery 主菜单
    1. 注意可能在 Wipe /data 分区时可能会出现错误:TWRP Unable to mount '/data',如果出现该错误,在 Fastboot 模式下运行 fastboot format userdata清理 /data 分区之后再进行操作
  4. 在电脑磁盘列表中找到手机,复制 ROM 至手机,复制完成后在 Recovery主菜单中,点击 Install,点击 ROM 包,滑动 Swipe to confirm Flash 进行刷入,重启设备
    1. 任意方法刷入 ROM 后,命令窗口中结束 adb 服务adb kill-server
  5. 重启进入 Recovery 模式,按照刷 ROM 的方式刷入 root 包

然后大功告成

参考资料

https://www.zhihu.com/question/50231539/answer/530627637
https://www.reddit.com/r/Nexus6P/comments/3qnzz0/twrp_unable_to_mount_data/

 

优化 wine 的字体显示

有时候总有一些不得不在 Linux 下跑一些 Windows 程序的需求,所以我们会用到 wine,但是 wine 默认并不是给中文用户设计的,因此我们需要一些办法来解决中文显示乱码和效果差的问题。

中文乱码,主要表现是非 ASCII 字符全部都显示为方框,这个是没有字体造成的,需要在 ~/.wine/drive_c/windows/Fonts 下面安装中文字体,一般来说,装好宋体、黑体和微软雅黑这些常用的就能用了,如果想装点别的,自然也可以。这里提供了一些打包好的基础字体下载:

cd ~/.wine/drive_c/windows/Fonts
wget https://down.gloriousdays.pw/Fonts/wine_fonts.tar.xz
tar cJvf wine_fonts.tar.xz
rm wine_fonts.tar.xz

搞定了字体以后,很快就会发现这些字体的显示效果十分差,完全没有做 AA 的意思,我们用 winetricks 解决这个问题:

apt install winetricks
winetricks settings fontsmooth=rgb

重新打开 exe 程序即可

使用 zram 进行内存压缩

对于像 KS-3 这样只有 4GB 内存的小内存服务器,如果想在上面跑一些比较复杂的服务,经常会遇到内存不足的问题。一般说到内存不足,第一反应都是加 swap 空间,但是对于机械硬盘的场景,添加盲目添加 swap 空间并不是一个好的选择,因为这样会显著增加系统整体的 latency。这个时候 zram 就可以派上用场了。

zram 是在 Linux Kernel 3.2 加入的一个模块,其功能是在内存中开辟一块空间,用来存储压缩后的内存数据,这样可以在牺牲一定的 CPU Cycle 的情况下,在内存中存储尽量多的数据而不需要写入到磁盘。

对于 Ubuntu 系统,开启 zram 的方法很简单,只需要安装 zram-config 这个包之后重启即可。zram 默认会将系统内存的一半作为 zram,然后根据 CPU 核心数平均分配到每个 zram 设备。比如在我的 KS-3 上,通过 zramctl 查看 zram 的情况,是这样的:

# zramctl
NAME       ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
/dev/zram3 lz4           491M   4K   63B    4K       4 [SWAP]
/dev/zram2 lz4           491M   4K   63B    4K       4 [SWAP]
/dev/zram1 lz4           491M   4K   63B    4K       4 [SWAP]
/dev/zram0 lz4           491M   4K   63B    4K       4 [SWAP]

注意到这里的压缩算法,有两种算法 lzo 和 lz4 可选,默认是 lzo。根据 Benchmark,lz4 的压缩和解压性能在压缩率和 lzo 持平的情况下显著高于后者,因此我们应该采用 lz4 而非 lzo 以获得更高的系统效率。

虽然 zramctl 可以帮助调整 zram 的情况,但是我们还是应该在系统启动时就将这些东西配置好。zram-config 安装好后会默认添加 zram-config.service,这个 service 是运行 /usr/bin/init-zram-swapping 这个脚本以配置对应的 zram 设备,默认情况下,其配置设备的内容应该是这样:

#!/bin/sh

# load dependency modules
NRDEVICES=$(grep -c ^processor /proc/cpuinfo | sed 's/^0$/1/')
if modinfo zram | grep -q ' zram_num_devices:' 2>/dev/null; then
  MODPROBE_ARGS="zram_num_devices=${NRDEVICES}"
elif modinfo zram | grep -q ' num_devices:' 2>/dev/null; then
  MODPROBE_ARGS="num_devices=${NRDEVICES}"
else
  exit 1
fi
modprobe zram $MODPROBE_ARGS

# Calculate memory to use for zram (1/2 of ram)
totalmem=`LC_ALL=C free | grep -e "^Mem:" | sed -e 's/^Mem: *//' -e 's/  *.*//'`
mem=$(((totalmem / 2 / ${NRDEVICES}) * 1024))

# initialize the devices
for i in $(seq ${NRDEVICES}); do
  DEVNUMBER=$((i - 1))
  echo $mem > /sys/block/zram${DEVNUMBER}/disksize
  mkswap /dev/zram${DEVNUMBER}
  swapon -p 5 /dev/zram${DEVNUMBER}
done

如果我们要默认使用 lz4 算法,那么应该将最后一段改成这样:

# initialize the devices
for i in $(seq ${NRDEVICES}); do
  DEVNUMBER=$((i - 1))
  echo lz4 > /sys/block/zram${DEVNUMBER}/comp_algorithm
  echo $mem > /sys/block/zram${DEVNUMBER}/disksize
  mkswap /dev/zram${DEVNUMBER}
  swapon -p 5 /dev/zram${DEVNUMBER}
done

注意算法设置一定要在配置空间大小之前,否则不能正确修改。

修改过后,运行 systemctl restart zram-config 就可以载入新的配置。

参考资料:

https://askubuntu.com/questions/1044976/make-zram-use-lz4-compression-algorithm
https://github.com/lz4/lz4
https://sites.google.com/site/easylinuxtipsproject/speed#TOC-Only-768-MB-RAM-or-less:-enable-zRam
http://tuxdiary.com/2015/07/28/zram/
https://wiki.archlinux.org/index.php/improving_performance#Zram_or_zswap

 

修改 Linux 默认的 IO Scheduler

RHEL 系我不知道怎么弄,我也没有机器是这个

在 /etc/default/grub 中,找到 GRUB_CMDLINE_LINUX_DEFAULT="" 这行,可能原来后面双引号中间有参数,这个各个机器不同,如果要修改默认的 CFQ Scheduler,那么在这里加上 elevator=noop 这样的内容,且和之前的旧内容有一空格。之后 update-grub2 重启即可。

之后 cat /sys/block/sda/queue/scheduler 就可以看到当前使用的调度器

IO Scheduler 有三个选择 cfq noop 和 deadline

参考资料:

https://www.ibm.com/developerworks/cn/linux/l-lo-io-scheduler-optimize-performance/index.html
https://askubuntu.com/questions/78682/how-do-i-change-to-the-noop-scheduler
Red_Hat_Enterprise_Linux-6-Performance_Tuning_Guide-en-US
Red_Hat_Enterprise_Linux-7-Performance_Tuning_Guide-en-US

iKoula 盒子的一些记录

之前听人整天听人吹 iKoula 网络好,但是因为性价比太低一直没买,这次黑五总算有性价比还行的型号,就买了台,真香

我这台是 109 段的 G 管,首先要配置一下 IPv6,运行这样一个脚本:

serveripv4=$( ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:" )
interface=$( ifconfig -a | grep -B 1 $serveripv4 | head -n1 | awk '{print $1}' | sed "s/:$//" )
AAA=$( echo $serveripv4 | awk -F '.' '{print $1}' )
BBB=$( echo $serveripv4 | awk -F '.' '{print $2}' )
CCC=$( echo $serveripv4 | awk -F '.' '{print $3}' )
DDD=$( echo $serveripv4 | awk -F '.' '{print $4}' )

cat>>/etc/network/interfaces<<EOF
iface $interface inet6 static
address 2a00:c70:1:$AAA:$BBB:$CCC:$DDD:1
netmask 96
gateway 2a00:c70:1:$AAA:$BBB:$CCC::1
EOF

然后 systemctl restart networking.service 就行了。

如果你像我一样运气不好,拿到了一块 WD 绿盘,IntelliPower 这种垃圾技术的盘,那么还得想办法拯救一下。绿盘默认 8 秒会把磁头停到启停区,这时候如果去读盘,就会卡一下,我们通过 idle3ctl 关闭这个功能:

sudo apt-get install idle3-tools
sudo apt-get install idle3-tools # Show current idle3 value
sudo idle3ctl -s 138 /dev/sda # setting to 300 seconds
# The man page for idle3ctl states that values between 1 and 128 add 0.1 seconds, values between 129 and 256 add 30s: 128 * 0.1 + (138 - 128) * 30 = 312.8 seconds
sudo idle3ctl -d /dev/sda # Disable parking, recommended

之后就是网卡,iKoula 的桌面主板用的是 RTL8168 这块开 BBR 会掉速 4MB 的螃蟹卡,我们需要更新驱动

由于 Realtek 的官网不太好使,我备份了驱动到自己的站点

apt update && apt install build-essential libelf-dev linux-headers-$(uname -r)
wget https://down.gloriousdays.pw/Tools/0012-r8168-8.046.00.tar.bz2
tar xjvf 0012-r8168-8.046.00.tar.bz2
cd r8168-8.046.00
./autorun.sh || modprobe r8169

这样就会安装上 R8168 的驱动了,之间会断网 3-5 分钟,之后重连即可,不需要 screen,但是如果一定要用也行。

如果 10 分钟还连不上,去后台手动重启。

参考资料:

https://wdullaer.com/blog/2015/04/05/hack-your-wd-greens/

 

关于 BT 客户端 Too many open files 的问题

感谢星菊对这个问题提供的帮助

换用 libtorrent 1.1 以后,由于 arvidn 改善了 IO 线程的问题,因此总是出现 too many open files 错误,在多方询问以后,终于解决了这个问题。

如果去查这个问题,通常会建议修改 limits.conf,修改 ulimit -n 参数,在 sysctl.conf 中添加 fs.file-max 参数等等,然而都不能解决这个问题。

实际上,目前以 systemd 作为启动工具的发行版,都存在两套限制体系,一个是 limits.conf,负责限制命令行模式启动的程序,另一个是 /etc/systemd/system.conf,限制以 systemd service 方式启动的程序。因此如果要解决这个问题,需要所有的地方都进行修改。

在 /etc/systemd/system.conf 中,加上:

DefaultLimitNOFILE=999998
DefaultLimitNPROC=999998

在 /etc/sysctl.conf 中,加上:

fs.file-max = 2097152
fs.nr_open = 2097152

在 /etc/security/limits.conf 中,加上:

*         hard    nofile      999999 
*         soft    nofile      999999 
root      hard    nofile      999999 
root      soft    nofile      999999 

然后就可以解决问题了。

 

如何查看 HBA 卡下的硬盘的 SMART 信息

盒子的盘挂了,但是这个盒子不是 SWR 的所以不太方便直接查看 SMART 信息。emm, 实际上还是很方便的。

我这个盒子是的 HWR 实际上通过一张 HBA 卡完成,信息是这样的:

root@dedi-par-28324:~# lspci|grep LSI
01:00.0 Serial Attached SCSI controller: LSI Logic / Symbios Logic SAS2008 PCI-Express Fusion-MPT SAS-2 [Falcon] (rev 03)

通过查看 SCSI 的信息,我们能看到卡下面连接的两块硬盘:

root@dedi-par-28324:~# cat /proc/scsi/scsi
Attached devices:
Host: scsi0 Channel: 01 Id: 00 Lun: 00
  Vendor: Dell     Model: Virtual Disk     Rev: 1028
  Type:   Direct-Access                    ANSI  SCSI revision: 06
Host: scsi0 Channel: 00 Id: 00 Lun: 00
  Vendor: ATA      Model: WDC WD2003FYYS-1 Rev: 1D02
  Type:   Direct-Access                    ANSI  SCSI revision: 05
Host: scsi0 Channel: 00 Id: 01 Lun: 00
  Vendor: ATA      Model: WDC WD2003FYYS-1 Rev: 1D02
  Type:   Direct-Access                    ANSI  SCSI revision: 05

如果要看 SMART 信息的话,只需要加载 sg 这个驱动就可以了(sg 为 Linux SCSI Generic driver 的缩写)

modprobe sg
echo sg >> /etc/modules

然后盘会挂在 sg1 sg2 这样的位置下面,用 # smartctl -a /dev/sg1 这样的命令就能看到 SMART 信息了。

在 $HOME 目录安装 Deluge 客户端

注意:这个教程是在 PulsedMedia 盒子上安装 Deluge 的实践,存在大量 platform-specific 的内容,在其他商家的盒子上尝试时要加以修改。

PulsedMedia 盒子的宿主机是 Ubuntu 14.04,所有自带的软件也是基于该发行版,自带的 Python 为 2.7.9,且缺乏大量的库。如果我们要安装 Deluge,需要从头解决一系列依赖问题。

在 User Space 编译安装的方法

比较清真的做法是创建 $HOME/.local 目录,然后在下面创建对应的 bin, lib 和 include 目录,然后再创建 usr 目录,并创建另一套 bin, lib 和 include。

在完成文件夹创建以后,在 .bashrc 中修改自己的 $PATH, $LD_LIBRARY_PATH, $C_INCLUDE_PATH, $CPLUS_INCLUDE_PATH 这几个环境变量:

export PATH=/home/<user>/.local/bin:/home/<user>/.local/usr/bin:$PATH
export LD_LIBRARY_PATH=/home/<user>/.local/lib:/home/<user>/.local/usr/lib:$LD_LIBRARY_PATH
export C_INCLUDE_PATH=/home/<user>/.local/include:/home/<user>/.local/usr/include:$C_INCLUDE_PATH
export CPLUS_INCLUDE_PATH=/home/<user>/.local/include:/home/<user>/.local/usr/include:$CPLUS_INCLUDE_PATH

<user> 修改为自己的 Unix 用户名

在修改了这些环境变量之后,配合编译时的 –prefix 参数以及 pip/python 的 –user 参数就可以将程序安装在自己的 $HOME 目录下

Deluge 依赖的安装

pip

对,你没看错,这机器 pip 都没有,好在这个相对来说还是比较简单,Python 官方也提供了对应的 py 程序

wget --no-check-certificate https://bootstrap.pypa.io/get-pip.py -O - | python - --user

Boost

libtorrent 编译需要 boost,我们选择 Boost 1.65.1 这个经过大量测试的版本

wget https://dl.bintray.com/boostorg/release/1.65.1/source/boost_1_65_1.tar.gz
tar xzvf boost_1_65_1.tar.gz
cd boost_1_65_1
./bootstrap.sh --prefix=$HOME/.local
./b2 install -j $(nproc)

Geoip

这也是 libtorrent 依赖的库之一

git clone https://github.com/maxmind/geoip-api-c.git
./bootstrap
./configure --prefix=$HOME/.local
make -j $(nproc)
make check
make install

libtorrent

终于可以安装 libtorrent 了,这个和之前正常安装的区别不大,唯一的区别在于要指定 –prefix 和 –with-boost-libdir

git clone https://github.com/arvidn/libtorrent.git libtorrent-1.0.11
git checkout RC_1_0
./autotool.sh
./configure --enable-python-binding --with-libiconv --disable-debug --enable-encryption --with-libgeoip=system CXXFLAGS=-std=c++11 --prefix=$HOME/.local --with-boost-libdir=$HOME/.local/lib
make -j $(nproc)
make install

Deluge 的 py 依赖

这个没什么好说的

pip install attr chardet click colorama pyopenssl pam pyasn1 pyasn1-modules serial service_identity Twisted zope.interface setuptools notify pygame mako automat constantly hyperlink incremental pyxdg --user

但是有三个库,intltool, libsrvg 和 xdg-utils 没有,我们需要另行安装

intltool

wget http://ftp.gnome.org/pub/gnome/sources/intltool/0.40/intltool-0.40.6.tar.gz
tar zxvf intltool-0.40.6.tar.gz
cd intltool-0.40.6
./configure --prefix=$HOME/.local
make && make install

libsrvg

该库依赖 librsvg2-common librsvg2-2 libglib2.0-0 和 libgdk-pixbuf,其中前三个可以直接用 apt-get download 命令取得,后一个不知为何没办法在 apt 上找到,只能去补佳乐的 package 网站上寻找,地址在这里。我们用的版本是 2.31.1-2+deb8u7。

使用 dpkg -x 命令可以将 .deb 包释放在指定目录下,但是不能完成 apt 安装的配置过程,好在这几个 library 只是文件而已,所以这么做并没有什么问题

apt-get download librsvg2-common librsvg2-2 libglib2.0-0
wget http://ftp.us.debian.org/debian/pool/main/g/gdk-pixbuf/libgdk-pixbuf2.0-0_2.31.1-2+deb8u7_amd64.deb
dpkg -x libgdk-pixbuf2.0-0_2.31.1-2+deb8u7_amd64.deb ~/.local
dpkg -x libglib2.0-0_2.42.1-1+b1_amd64.deb ~/.local
dpkg -x librsvg2-2_2.40.5-1+deb8u2_amd64.deb ~/.local
dpkg -x librsvg2-common_2.40.5-1+deb8u2_amd64.deb ~/.local

注意 .deb 的名字可能随着版本升级而改变,所以复用的时候要注意一下

xdg-utils

和上面一样,用 apt 取得包以后再释放

apt-get download xdg-utils
dpkg -x xdg-utils_1.1.0~rc1+git20111210-7.4_all.deb ~/.local

Deluge

最后,正常安装 deluge 即可

wget http://download.deluge-torrent.org/source/deluge-1.3.15.tar.gz
tar xzvf deluge*.tar.gz
python setup.py build
python setup.py install --user

之后 deluged 和 deluge-web 会被安装在 $HOME/.local/bin 下面,由于之前已经修改了环境变量,所以直接运行就可以了

如果要让 deluged 工作在不同的端口,使用 deluged -p 23333 这样的命令就行,然后在 deluge-web 中改一下连接的 daemon 端口就行了

至此,deluge 应该已经可以正常运行了。

 

关于 Docker 中 tty 尺寸不太对的问题

不知道为啥就是不行,不过本来就对 docker 这玩意没啥好感。

$ docker exec -it foo /bin/bash
foo@649fb21d747c:~$ stty size
0 0
foo@649fb21d747c:~$ reset -w
foo@649fb21d747c:~$ stty size
24 80
foo@649fb21d747c:~$ # That was still wrong. Now resize the terminal to get a SIGWINCH.
foo@649fb21d747c:~$ stty size
69 208
foo@649fb21d747c:~$ exit
exit
$ docker exec -it foo /bin/bash # Try it again.
foo@649fb21d747c:~$ stty size
69 208
foo@649fb21d747c:~$ # Doesn't happen anymore for this session.