【Joytag 香蕉R1学习】OpenWrt for R1, 也谈扩展系统分区

原文信息

标题:【Joytag 香蕉R1学习】OpenWrt for R1, 也谈扩展系统分区
连接:http://forum.godpub.com/thread-86-1-1.html
备注:狗趴论坛首发,转载请注明出处。
**

折腾缘起**

在之前的一系列文章中,我们自动组装了一个OpenWrt for R1,使R1具备了有线以及无线路由器的基本功能。
关于如何组装OpenWrt for R1,请参考:
【Joytag 香蕉R1学习】自己动手组装OpenWrt for R1(全)
在这个系列文章中,我们使用240M空间用来做系统分区。
虽然目前为止我尚未遇到过空间不足,但是很明显这个空间分配有些小,而且一般我们使用8G或者16G TF(SD)卡,剩余空间也是一种浪费。
所以扩展系统分区到整个TF(SD)卡,似乎很有必要。

撸神的做法

http://www.52pi.net/forum.php?mod=viewthread&tid=1423
撸神的一篇文章,详细的讲述了如何扩展系统分区

基本思路就是
[list]
*]使用fdisk重新对TF(SD)卡进行分区
*]然后使用resize2fs调整文件系统(使用其它PC)
[/list]
其中Openwrt默认没有安装fdisk工具,需要执行如下命令安装:

# opkg update
# opkg install fdisk

其中一个需要注意的地方就是,TF(SD)卡第二个分区的起始扇区,也许和第一个不是连续的
这种情况必须记住原本的第二个分区的起始扇区,新分区使用相同的起始扇区,否则会对数据造成破坏,导致系统不可用。

撸神使用的方法是:

# cat /sys/block/mmcblk0/mmcblk0p2/start

其实只需用fdisk操作对应TF(SD)卡,用p命令,或者-l参数就可以直接查看。

尽管我们可以在OpenWrt上安装resize2fs工具包,但是系统内核不支持在线调整(Online Resize)

resize2fs: Filesystem does not support online resizing

撸神的方案是将TF(SD)卡拿到另外的机器上,使用resize2fs调整文件系统。
(既然需要另外的机器,那么其实可以将fdisk的步骤也放到另外机器上操作)

Raspbian的做法

使用过Raspbian的朋友,都会对raspi-config命令不陌生。
使用raspi-config可以方便的进行扩展系统分区到整个TF(SD)卡。

以下为香蕉派中raspi-config的部分代码:

do_expand_rootfs() {
  if !  -h /dev/root ]; then
   whiptail --msgbox "/dev/root does not exist or is not a symlink. Don't know how to expand" 20 60 2
   return 0
  fi

  ROOT_PART=$(readlink /dev/root)
  PART_NUM=${ROOT_PART#mmcblk0p}
  if  "$PART_NUM" = "$ROOT_PART" ]; then
   whiptail --msgbox "/dev/root is not an SD card. Don't know how to expand" 20 60 2
   return 0
  fi

  # NOTE: the NOOBS partition layout confuses parted. For now, let's only
  # agree to work with a sufficiently simple partition layout
  if  "$PART_NUM" -ne 2 ]; then
   whiptail --msgbox "Your partition layout is not currently supported by this tool. You are probably using NOOBS, in which case your root filesystem is already expanded anyway." 20 60 2
   return 0
  fi

  LAST_PART_NUM=$(parted /dev/mmcblk0 -ms unit s p | tail -n 1 | cut -f 1 -d:)

  if  "$LAST_PART_NUM" != "$PART_NUM" ]; then
   whiptail --msgbox "/dev/root is not the last partition. Don't know how to expand" 20 60 2
   return 0
  fi

  # Get the starting offset of the root partition
  PART_START=$(parted /dev/mmcblk0 -ms unit s p | grep "^${PART_NUM}" | cut -f 2 -d:)
   "$PART_START" ] || return 1
  # Return value will likely be error for fdisk as it fails to reload the
  # partition table because the root fs is mounted
  fdisk /dev/mmcblk0 <<EOF
p
d
$PART_NUM
n
p
$PART_NUM
$PART_START

p
w
EOF
  ASK_TO_REBOOT=1

  # now set up an init.d script
cat <<\EOF > /etc/init.d/resize2fs_once &&
#!/bin/sh
### BEGIN INIT INFO
# Provides:          resize2fs_once
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5 S
# Default-Stop:
# Short-Description: Resize the root filesystem to fill partition
# Description:
### END INIT INFO

. /lib/lsb/init-functions

case "$1" in
  start)
   log_daemon_msg "Starting resize2fs_once" &&
   resize2fs /dev/root &&
   rm /etc/init.d/resize2fs_once &&
   update-rc.d resize2fs_once remove &&
   log_end_msg $?
   ;;
  *)
   echo "Usage: $0 start" >&2
   exit 3
   ;;
esac
EOF
  chmod +x /etc/init.d/resize2fs_once &&
  update-rc.d resize2fs_once defaults &&
  if  "$INTERACTIVE" = True ]; then
   whiptail --msgbox "Root partition has been resized.\nThe filesystem will be enlarged upon the next reboot" 20 60 2
  fi
}

通过分析,我们可知脚本主要执行如下操作:
[list]
*]删除原有分区
*]使用相同的起始扇面创建新分区
*]创建执行一次的启动脚本,下次启动试在此脚本中执行resize2fs对文件系统进行调整,并删除此脚本
[/list]
基本思路与撸神的操作相同,但是涉及系统启动,分区挂载等复杂操作,就不深入研究了。

我们的思路

对于我们这个OpenWrt for R1,这部分工作可以进一步简化。
因为,OpenWrt for R1原本的操作过程中包含了fdisk分区操作。
所以我们可以直接在分区的步骤中,将第二分区直接设置为剩余空间大小,也无需考虑起始扇面之类的问题。

另外一个步骤是resize2fs对文件系统进行调整
因为我们原本就是另外的系统内操作TF(SD)卡,所以对之调整也非常方便。

在这篇文章中:
【Joytag 香蕉R1学习】自己动手组装OpenWrt for R1(全)
脚本mksys.sh (将OpenWrt for R1写入SD卡)有如下相关操作:
[list]
*]调用fdisk对TF(SD)卡进行分区
*]调整根文件系统镜像大小以符合分区大小
*]创建根文件系统
[/list]
我们可以将这几个步骤做些修改:
[list]
*]调用fdisk对TF(SD)卡进行分区(根据需要选择是否让分区2使用所有剩余空间)
*]创建根文件系统
*]调整根文件系统大小以符合分区大小
[/list]
在mksys.sh脚本中,添加如下内容:
其中p2size可以是我们指定的大小,比如240M;或者使用所有剩余空间,FULL

p2size=FULL
if  $p2size != FULL ]; then
   p2size=+${p2size}
else
   p2size=
fi

echo $p2size
sleep 2s

然后,对应的fdisk操作更新如下:

fdisk $1<<EOF
p
d
1
d
p
n
p
1

+15M
n
p
2

${p2size}
t
1
c
p
w
EOF

然后修改以下内容:

#echo -e "\n......8) Resize the root filesystem image to match the partition size."
#resize2fs openwrt-sunxi-root.ext4 240M

echo -e "\n......8)  Create the root filesystem."
dd if=openwrt-sunxi-root.ext4 of=${disk}2 bs=128k

echo -e "\n......9) Resize the root filesystem to match the partition size."
resize2fs ${disk}2

这样是不是很方便了呢?

总结

因为这个OpenWrt for R1,是我们自己动手组装的,所以对其操作也比较自由。
我们可以在生成系统的同时设置根文件系统使用的空间大小,或者使用整个剩余TF(SD)卡空间。
对于16G的TF(SD)卡,执行resize2fs耗时大约10分钟左右。

在调试期间我们可以将这个空间设置的小一些,比如200M,这样生成系统会较快,方便我们随时测试。
而在正式使用的系统中,我们可以将根文件系统扩展至整个剩余TF(SD)卡空间,方便我们使用。

撸神的做法最棒啦!

那是当然了
不然何以成神呢:lol

话说 为什么 你们弄系统 都是直接映像文件写入呢…
直接mount 复制分区的文件不久好了么…
当初 我高中的时候 树莓派的系统都是这么弄了,那时候没电脑 还是直接用手机弄得。:stuck_out_tongue:
直接mount 复制分区的文件还能免得resize.
哦 对了 树莓派启动是根据第一fat32分区读入启动文件。所以直接手动分区复制文件可行。
不知道banana pi的启动是怎么启动的。

:’(因为笨呗:’(