update 2025-03-26 14:11:27

This commit is contained in:
actions-user 2025-03-26 14:11:27 +08:00
parent c621c09cb1
commit 95244b6a2b
18 changed files with 852 additions and 607 deletions

View File

@ -30,6 +30,17 @@ luci-app-partexp 一键自动格式化分区、扩容、自动挂载插件
<!-- /TOC -->
## 版本
- 最新更新版本号: V1.3.1
- 更新日期2025年3月26日
- 更新内容:
- 重新整理分区扩容代码,解决一些不合理的地方。
- 加入对目标分区的格式可以指定格式化为ext4,ntfs和Btrfs以及不格式化。
- 当做为根目录 /或者 /overlay时密然会格式化为ext4格式。
- 目前在X86的机器上测试完全正常其它路由设备上未测试。有问题请提交硬盘分区情况和错误提示。
## 特性
luci-app-partexp 自动获格式化分区扩容,自动挂载插件
@ -67,7 +78,7 @@ luci-app-partexp 一键自动格式化分区、扩容、自动挂载插件
## 界面
![screenshots](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/partexp.jpg)
![screenshots](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/partexp.png)

View File

@ -1,41 +0,0 @@
--[[
LuCI - Lua Configuration Interface
Copyright (C) 2022 sirpdboy <herboy2008@gmail.com> https://github.com/sirpdboy/partexp
]]--
local fs = require "nixio.fs"
local util = require "nixio.util"
local tp = require "luci.template.parser"
local uci=luci.model.uci.cursor()
local ver = require "luci.version"
local d.list_disks = function()
-- get all device names (sdX and mmcblkX)
local target_devnames = {}
for dev in fs.dir("/dev") do
if dev:match("^sd[a-z]$")
or dev:match("^mmcblk%d+$")
or dev:match("^sata[a-z]$")
or dev:match("^nvme%d+n%d+$")
or dev:match("^vd[a-z]$")
then
table.insert(target_devnames, dev)
end
end
local devices = {}
for i, bname in pairs(target_devnames) do
local device_info = {}
local device = "/dev/" .. bname
device_info["name"] = bname
device_info["dev"] = device
s = tonumber((fs.readfile("/sys/class/block/%s/size" % bname)))
device_info["size"] = s and math.floor(s / 2048)
devices[#devices+1] = device_info
end
return devices
end
return d

View File

@ -1,16 +0,0 @@
<%+cbi/valueheader%>
<textarea id="logview.list" class="cbi-input-textarea" style="width: 100%" rows="20" readonly="readonly"></textarea>
<script type="text/javascript">
const LOG_URL = '<%=luci.dispatcher.build_url("admin", "system", "partexp","realtime_log")%>';
XHR.poll(1, LOG_URL, null, (x, d) => {
let logview = document.getElementById("logview.list");
if (!d.running) {
XHR.halt();
}
logview.value = d.log;
logview.scrollTop = logview.scrollHeight;
});
</script>
<%+cbi/valuefooter%>

View File

@ -1,5 +1,5 @@
#
# Copyright (C) 2020-2022 sirpdboy <herboy2008@gmail.com>
# Copyright (C) 2020-2025 sirpdboy <herboy2008@gmail.com>
#
# This is free software, licensed under the GNU General Public License v3.
#
@ -7,14 +7,14 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-partexp
PKG_VERSION:=1.2.1
PKG_RELEASE:=20250315
PKG_VERSION:=1.3.1
PKG_RELEASE:=20250326
PKG_LICENSE:=Apache-2.0
PKG_MAINTAINER:=Sirpdboy <herboy2008@gmail.com>
LUCI_TITLE:=LuCI Support for Automatic Partition Mount
LUCI_DEPENDS:=+fdisk +block-mount +bc +parted
LUCI_DEPENDS:=+fdisk +block-mount +bc +blkid +parted
LUCI_PKGARCH:=all

View File

@ -0,0 +1,127 @@
### 访问数:[![](https://visitor-badge.glitch.me/badge?page_id=sirpdboy-visitor-badge)] [![](https://img.shields.io/badge/TG群-点击加入-FFFFFF.svg)](https://t.me/joinchat/AAAAAEpRF88NfOK5vBXGBQ)
![screenshots](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/说明1.jpg)
=
# luci-app-partexp
luci-app-partexp 一键自动格式化分区、扩容、自动挂载插件
[![若部分图片无法正常显示,请挂上机场浏览或点这里到末尾看修复教程](https://visitor-badge.glitch.me/badge?page_id=sirpdboy-visitor-badge)](#解决-github-网页上图片显示失败的问题) [![](https://img.shields.io/badge/TG群-点击加入-FFFFFF.svg)](https://t.me/joinchat/AAAAAEpRF88NfOK5vBXGBQ)
[luci-app-partexp](https://github.com/sirpdboy/luci-app-partexp)
======================
**认真阅读完毕** 本页面,本页面包含注意事项和如何使用。
## 功能说明:
#### 一键自动格式化分区、扩容、自动挂载插件专为OPENWRT设计简化OPENWRT在分区挂载上烦锁的操作。本插件是sirpdboy耗费大量精力制作测试请勿删除制作者信息
<!-- TOC -->
- [partexp](#luci-app-partexp)
- [特性](#特性)
- [使用方法](#使用方法)
- [说明](#说明)
- [界面](#界面)
- [捐助](#捐助)
<!-- /TOC -->
## 版本
- 最新更新版本号: V1.3.1
- 更新日期2025年3月26日
- 更新内容:
- 重新整理分区扩容代码,解决一些不合理的地方。
- 加入对目标分区的格式可以指定格式化为ext4,ntfs和Btrfs以及不格式化。
- 当做为根目录 /或者 /overlay时密然会格式化为ext4格式。
- 目前在X86的机器上测试完全正常其它路由设备上未测试。有问题请提交硬盘分区情况和错误提示。
## 特性
luci-app-partexp 自动获格式化分区扩容,自动挂载插件
## 使用方法
- 将luci-app-partexp添加至 LEDE/OpenWRT 源码的方法。
### 下载源码方法:
```Brach
# 下载源码
git clone https://github.com/sirpdboy/luci-app-partexp.git package/luci-app-partexp
make menuconfig
```
### 配置菜单
```Brach
make menuconfig
# 找到 LuCI -> Applications, 选择 luci-app-partexp, 保存后退出。
```
### 编译
```Brach
# 编译固件
make package/luci-app-partexp/compile V=s
```
## 说明
![screenshots](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/说明2.jpg)
## 界面
![screenshots](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/partexp.png)
## 使用与授权相关说明
- 本人开源的所有源码,任何引用需注明本处出处,如需修改二次发布必告之本人,未经许可不得做于任何商用用途。
# My other project
- 网络速度测试 https://github.com/sirpdboy/NetSpeedTest
- 定时设置插件 : https://github.com/sirpdboy/luci-app-autotimeset
- 关机功能插件 : https://github.com/sirpdboy/luci-app-poweroffdevice
- opentopd主题 : https://github.com/sirpdboy/luci-theme-opentopd
- kucat 主题: https://github.com/sirpdboy/luci-theme-kucat
- 家长控制: https://github.com/sirpdboy/luci-theme-parentcontrol
- 系统高级设置 : https://github.com/sirpdboy/luci-app-advanced
- ddns-go动态域名: https://github.com/sirpdboy/luci-app-ddns-go
- 进阶设置(系统高级设置+主题设置kucat/agron/opentopd: https://github.com/sirpdboy/luci-app-advancedplus
- 设置向导: https://github.com/sirpdboy/luci-app-wizard
- 分区扩容: https://github.com/sirpdboy/luci-app-partexp
- lukcy大吉: https://github.com/sirpdboy/luci-app-lukcy
## 捐助
![screenshots](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/说明3.jpg)
| <img src="https://img.shields.io/badge/-支付宝-F5F5F5.svg" href="#赞助支持本项目-" height="25" alt="图飞了😂"/> | <img src="https://img.shields.io/badge/-微信-F5F5F5.svg" height="25" alt="图飞了😂" href="#赞助支持本项目-"/> |
| :-----------------: | :-------------: |
|![xm1](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/支付宝.png) | ![xm1](https://raw.githubusercontent.com/sirpdboy/openwrt/master/doc/微信.png) |
<a href="#readme">
<img src="https://img.shields.io/badge/-返回顶部-orange.svg" alt="图飞了😂" title="返回顶部" align="right"/>
</a>

View File

@ -1,6 +1,6 @@
--[[
LuCI - Lua Configuration Partition Expansion
Copyright (C) 2022-2024 sirpdboy <herboy2008@gmail.com> https://github.com/sirpdboy/partexp
Copyright (C) 2022-2025 sirpdboy <herboy2008@gmail.com> https://github.com/sirpdboy/partexp
]]--
local fs = require "nixio.fs"
@ -34,12 +34,12 @@ end
function partexprun()
local kconfig = http.formvalue('kconfig')
local aformat = http.formvalue('aformat')
local eformat = http.formvalue('eformat')
local targetf = http.formvalue('targetf')
local targetd = http.formvalue('targetd')
uci:set(name, 'global', 'target_disk', targetd)
uci:set(name, 'global', 'target_function', targetf)
uci:set(name, 'global', 'auto_format', aformat)
uci:set(name, 'global', 'format_type', eformat)
uci:set(name, 'global', 'keep_config', kconfig)
uci:commit(name)
fs.writefile("/tmp/lucilogpos","0")

View File

@ -1,6 +1,6 @@
--[[
LuCI - Lua Configuration Interface
Copyright (C) 2022 sirpdboy <herboy2008@gmail.com> https://github.com/sirpdboy/luci-app-partexp
Copyright (C) 2022-2025 sirpdboy <herboy2008@gmail.com> https://github.com/sirpdboy/luci-app-partexp
]]--
local fs = require "nixio.fs"
local util = require "nixio.util"
@ -39,10 +39,10 @@ t=m:section(TypedSection,"global")
t.anonymous=true
e=t:option(ListValue,"target_function", translate("Select function"),translate("Select the function to be performed"))
e:value("/", translate("Used to expand to EXT4 root directory(Ext4 /)"))
e:value("/", translate("Used to extend to the root directory of EXT4 firmware(Ext4 /)"))
e:value("/overlay", translate("Expand application space overlay (/overlay)"))
e:value("/opt", translate("Used as Docker data disk (/opt)"))
e:value("/dev", translate("Normal mount and use by device name(/dev/x1)"))
e:value("/dev", translate("Normal mount and use by device name(/mnt/x1)"))
e.default="/opt"
e=t:option(ListValue,"target_disk", translate("Destination hard disk"),translate("Select the hard disk device to operate"))
@ -59,10 +59,14 @@ e:depends("target_function", "/overlay")
e:depends("target_function", "/")
e.default=0
e=t:option(Flag,'auto_format', translate('Format before use'),translate("Ticking indicates formatting"))
e=t:option(ListValue,'format_type', translate('Format system type'))
e:depends("target_function", "/opt")
e:depends("target_function", "/dev")
e.default=0
e:value("0", translate("No formatting required"))
e:value("ext4", translate("Linux system partition(EXT4)"))
e:value("btrfs", translate("Large capacity storage devices(Btrfs)"))
e:value("ntfs", translate("Windows system partition(NTFS)"))
e.default="0"
e=t:option(Button, "restart", translate("Perform operation"))
e.inputtitle=translate("Click to execute")

View File

@ -74,11 +74,10 @@ function apply_run(btn){
var targetf=opt.get("target_function").value;
var targetd=opt.get("target_disk").value;
if (opt.get("auto_format"))
var aformat = opt.get("auto_format").checked ? 1 : 0;
if (opt.get("format_type"))
var eformat=opt.get("format_type").value;
else
var aformat = 0;
var aformat = "0";
if (opt.get("keep_config"))
var kconfig = opt.get("keep_config").checked ? 1 : 0;
else
@ -89,7 +88,7 @@ function apply_run(btn){
targetf: targetf,
kconfig: kconfig,
targetd: targetd,
aformat: aformat
eformat: eformat
},function(x){});
poll_check();
return

View File

@ -1,6 +1,6 @@
msgid ""
msgstr ""
"Copyright (C) 2022-2024 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-partexp"
"Copyright (C) 2022-2025 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-partexp"
"This is free software, licensed under the GNU General Public License v3."
msgid "Partition Expansion"
@ -18,14 +18,14 @@ msgstr "稍等,努力执行中"
msgid "Expand application space overlay (/overlay)"
msgstr "用于overlay软件空间 (/overlay)"
msgid "Used to expand to EXT4 root directory(Ext4 /)"
msgstr "用于扩展为EXT4根目录(Ext4 /)"
msgid "Used to extend to the root directory of EXT4 firmware(Ext4 /)"
msgstr "用于扩展为EXT4固件根目录(Ext4 /)"
msgid "Used as Docker data disk (/opt)"
msgstr "用作Docker数据盘 (/opt)"
msgid "Normal mount and use by device name(/dev/x1)"
msgstr "按设备名普通挂载使用(/dev/x1)"
msgid "Normal mount and use by device name(/mnt/x1)"
msgstr "按设备名普通挂载使用(/mnt/x1)"
msgid "Soft chain partition expansion(/overlay)"
msgstr "分区软链扩容(/overlay)"
@ -36,8 +36,20 @@ msgstr "目标硬盘"
msgid "Keep configuration"
msgstr "保留配置"
msgid "Format before use"
msgstr "使用前格式化"
msgid "Format system type"
msgstr "格式化系统类型"
msgid "No formatting required"
msgstr "不需要格式化"
msgid "Linux system partition(EXT4)"
msgstr "Linux系统分区(EXT4)"
msgid "Large capacity storage devices(Btrfs)"
msgstr "大容量存储设备(Btrfs)"
msgid "Windows system partition(NTFS)"
msgstr "Windows系统分区(NTFS)"
msgid "Select the hard disk device to operate"
msgstr "选择需要操作的硬盘设备"

View File

@ -1,6 +1,6 @@
msgid ""
msgstr ""
"Copyright (C) 2022-2024 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-partexp"
"Copyright (C) 2022-2025 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-partexp"
"This is free software, licensed under the GNU General Public License v3."
msgid "Partition Expansion"
@ -18,14 +18,14 @@ msgstr "稍等,努力执行中"
msgid "Expand application space overlay (/overlay)"
msgstr "用于overlay软件空间 (/overlay)"
msgid "Used to expand to EXT4 root directory(Ext4 /)"
msgstr "用于扩展为EXT4根目录(Ext4 /)"
msgid "Used to extend to the root directory of EXT4 firmware(Ext4 /)"
msgstr "用于扩展为EXT4固件根目录(Ext4 /)"
msgid "Used as Docker data disk (/opt)"
msgstr "用作Docker数据盘 (/opt)"
msgid "Normal mount and use by device name(/dev/x1)"
msgstr "按设备名普通挂载使用(/dev/x1)"
msgid "Normal mount and use by device name(/mnt/x1)"
msgstr "按设备名普通挂载使用(/mnt/x1)"
msgid "Soft chain partition expansion(/overlay)"
msgstr "分区软链扩容(/overlay)"
@ -36,8 +36,20 @@ msgstr "目标硬盘"
msgid "Keep configuration"
msgstr "保留配置"
msgid "Format before use"
msgstr "使用前格式化"
msgid "Format system type"
msgstr "格式化系统类型"
msgid "No formatting required"
msgstr "不需要格式化"
msgid "Linux system partition(EXT4)"
msgstr "Linux系统分区(EXT4)"
msgid "Large capacity storage devices(Btrfs)"
msgstr "大容量存储设备(Btrfs)"
msgid "Windows system partition(NTFS)"
msgstr "Windows系统分区(NTFS)"
msgid "Select the hard disk device to operate"
msgstr "选择需要操作的硬盘设备"

View File

@ -2,4 +2,4 @@ config global 'global'
option target_function '/opt'
option target_disk ''
option keep_config '0'
option auto_format '0'
option format_type '0'

View File

@ -0,0 +1,654 @@
#!/bin/sh /etc/rc.common
#
# Copyright (C) 2021-2025 sirpdboy <herboy2008@gmail.com> https://github.com/sirpdboy/partexp
# This is free software, licensed under the Apache License, Version 2.0 .
#
START=99
USE_PROCD=1
EXTRA_COMMANDS="autopart"
LOCK=/var/lock/partexp.lock
LOGD=/var/partexp
LOG=$LOGD/partexp.log
[ -d "$LOGD" ] || mkdir -p $LOGD
limit_log() {
local logf=$1
[ ! -f "$logf" ] && return
local sc=100
[ -n "$2" ] && sc=$2
local count=$(grep -c "" $logf)
if [ $count -gt $sc ];then
let count=count-$sc
sed -i "1,$count d" $logf
fi
}
init_env() {
[ ! -f "$LOG" ] && echo " " > $LOG
}
gen_log()(
log "---------------自动分区扩展挂载开始执行------------------ "
)
log(){
echo -e " $(date +'%Y-%m-%d %H:%M:%S') $*"
}
_uci_get() {
local ret=$(uci get partexp.global.$1 2>/dev/null)
echo ${ret:=$2}
}
uci_get() {
case $# in
2)
local ret=$(uci get $1.$2 2>/dev/null)
echo ${ret}
;;
3)
local ret=$(uci get $1.$2.$3 2>/dev/null)
echo ${ret}
;;
4)
local ret=$(uci get $1.$2.$3 2>/dev/null)
echo ${ret:=$4}
;;
esac
}
uci_set() {
case $# in
3)
uci set $1.$2=$3 2>/dev/null
uci commit $1
;;
4)
uci set $1.$2.$3=$4 2>/dev/null
uci commit $1
;;
esac
}
uci_add(){
uci add_list $1.$2.$3=$4 2>/dev/null
uci commit $1
}
uci_del() {
case $# in
2)
uci delete "$1.$2"
;;
3)
uci delete "$1.$2.$3"
;;
4)
uci delete "$1.$2.$3.$4"
;;
esac
}
# 检查硬盘是否已挂载
is_disk_mounted() {
DISK=$1
if mount | grep -q "$DISK "; then
return 0 # 已挂载
else
return 1 # 未挂载
fi
}
mount_device() {
local DEVICE=$1
local MOUNT_POINT=$2
local TYPE=$3
# 检查设备是否存在
if [ ! -e "$DEVICE" ]; then
log "设备 $DEVICE 不存在"
return 1
fi
# 检查挂载点是否存在
if [ ! -d "$MOUNT_POINT" ]; then
log "挂载点 $MOUNT_POINT 不存在,正在创建..."
mkdir -p "$MOUNT_POINT"
if [ $? -ne 0 ]; then
log "无法创建挂载点 $MOUNT_POINT"
return 1
fi
fi
# 检查设备是否已挂载
if mount | grep -q "$DEVICE"; then
log "设备 $DEVICE 已挂载到其他位置"
return 1
fi
if mount | grep -q "$MOUNT_POINT"; then
log "挂载点 $MOUNT_POINT 已被其他设备占用"
return 1
fi
# 挂载设备
log "正在挂载 $DEVICE 到 $MOUNT_POINT..."
# mount "$DEVICE" "$MOUNT_POINT"
mount $TYPE "$DEVICE" "$MOUNT_POINT" >/dev/null 2> /dev/null
# 检查挂载是否成功
if [ $? -eq 0 ]; then
log "挂载成功: $DEVICE -> $MOUNT_POINT"
return 0
else
log "挂载失败: $DEVICE -> $MOUNT_POINT"
return 1
fi
}
# 取消硬盘挂载
umount_disk() {
DISK=$1
MOUNT=''
eval $(block info "$DISK" | grep -o -e "MOUNT=\S*")
if [ "$MOUNT" ]; then
umount $DISK 2>/dev/null
if [ $? -eq 0 ]; then
log "取消挂载成功:$DISK"
else
log "取消挂载失败:$DISK"
fi
else
log "设备/dev/$DISK未挂载"
fi
}
# 从 block info 中提取指定字段的值
get_block() {
local DISK=$1
local TYPE=$2
local value
value=`mount | grep $DISK |awk -F $TYPE '{print $2}' |awk '{print $1}' | head -1`
# value=$(block info "/dev/$DISK" | grep -o -e "$TYPE=\S*" | cut -d\" -f2)
echo $value
}
# 检查是否有共享挂载(如 Samba 或 NFS
check_shared_mount() {
DISK=$1
if [ -f /etc/config/samba ]; then
SHARED=$(grep -q "/dev/$DISK" /etc/config/samba)
if [ $? -eq 0 ]; then
log "检测到 Samba 共享挂载: /dev/$DISK"
return 0
fi
fi
# 检查是否有 NFS 共享
if [ -f /etc/exports ]; then
SHARED=$(grep -q "/dev/$DISK" /etc/exports)
if [ $? -eq 0 ]; then
log "检测到 NFS 共享挂载: /dev/$DISK"
return 0
fi
fi
return 1
}
usamba(){
s=$1
[ -e "/etc/config/$s" ] && {
msum=$(grep -c "config sambashare" /etc/config/$s)
for i in $(seq 0 $((msum)));do
pdev=`uci_get $s @sambashare[$i] path `
[ "$pdev" = "$2" ] && {
uci_del $s @sambashare[$i]
log "分区/dev/$b被挂载$MOUNT共享使用删除$s共享成功"
sleep 1
}
done
}
# 取消 Samba 共享
if [ -f /etc/config/$s ]; then
sed -i "/\/dev\/$b/d" /etc/config/$s
/etc/init.d/$s restart
fi
# 取消 NFS 共享
if [ -f /etc/exports ]; then
sed -i "/\/dev\/$b/d" /etc/exports
/etc/init.d/nfs restart
fi
}
is_disk_partitioned() {
PARTITION_COUNT=$(fdisk -l /dev/$1 2>/dev/null | grep -E "^/dev/$2" | wc -l)
if [[ "$PARTITION_COUNT" -gt 0 ]]; then
echo 1
else
echo 0
fi
}
partednew(){
DISK=$1
parted -s /dev/$DISK mklabel gpt
parted -s /dev/$DISK mkpart primary ext4 1MiB -1
}
fdisknew(){
echo -e "n\np\n\n\n\nw" | fdisk /dev/$1 >/dev/null 2> /dev/null
}
fdisksave(){
echo -e "n\w" | fdisk /dev/$1 >/dev/null 2> /dev/null
}
# 格式化磁盘函数 DISK=/dev/sda1 ;TYPE=btrfs
format_disk() {
local DISK=$1
local TYPE=$2
[ $TYPE == '0' ] && TYPE="ext4"
log "正在格式化 $DISK "
mkfs.$TYPE -F "$DISK" >/dev/null 2>/dev/null
if [ $? -eq 0 ]; then
log "格式化 $TYPE 成功 $DISK"
return 0
else
log "格式化 $TYPE 失败 $DISK"
return 1
fi
}
fdiskB(){
target_function=$( _uci_get target_function "/opt" )
format_type=$( _uci_get format_type)
keep_config=$( _uci_get keep_config "1" )
uci_set fstab @global[0] anon_mount '0'
uci_set fstab @global[0] auto_mount '0'
a=$( _uci_get target_disk "/sda3" )
local b=$a$1
log "开始检测目标$a信息"
log "检测/dev/$b是否需要分区和格式化$format_type"
[ -e "/etc/config/dockerd" ] && /etc/init.d/dockerd stop >/dev/null 2> /dev/null
[ -e "/etc/config/fstab" ] || block detect > /etc/config/fstab
[ -d "/mnt/$b" ] || mkdir -p /mnt/$b
if is_disk_mounted "/dev/$b"; then
log "设备 /dev/$b 已挂载,尝试取消挂载..."
if check_shared_mount $b; then
usamba samba4 $MOUNT
usamba samba $MOUNT
sleep 5
fi
umount_disk "/dev/$b" || umount_disk "/mnt/$b"
else
log "设备/dev/$b未挂载"
isfdisk=0
isP=$(is_disk_partitioned $a $b)
if [ "$isP" == '0' ] ;then
fdisksave $a
fdisknew $a
sleep 2
isfdisk=1
fi
isP=$(is_disk_partitioned $a $b)
if [ $isP == '1' -a "$isfdisk" == 1 ] ;then
log "分区$b建立成功"
elif [ $isP == '1' -a "$isfdisk" = 0 ] ;then
log "检测目标分区$b已存在."
else
log "分区$b建立失败请检查$b硬盘空间"
expquit 1
fi
sleep 1
fi
if is_disk_mounted "/dev/$b"; then
umount /dev/$b >/dev/null 2> /dev/null
[ $? -ne 0 ] && block umount /dev/$b >/dev/null 2> /dev/null
fi
if [ "$target_function" = "/" -o "$target_function" = "/overlay" ] ; then
format_disk "/dev/$b" $format_type
elif [ "$format_type" != "0" -o "$isfdisk" = "1" ] ; then
format_disk "/dev/$b" $format_type
else
log "设备/dev/$b如果未格式化,可能无法正常使用."
fi
TYPE='';eval $(blkid "/dev/$b" | grep -o -e "TYPE=\S*")
log "检测设备/dev/$b分区$TYPE格式"
if [ "$TYPE" = "ntfs" ];then
if [ `which ntfs-3g ` ] ;then
if is_disk_mounted "/mnt/$b" ;then
mount_device /dev/$b /mnt/$b "-t ntfs-3g"
fi
else
if is_disk_mounted "/mnt/$b" ;then
mount_device /dev/$b /mnt/$b "-t ntfs3"
fi
fi
else
mount /dev/$b /mnt/$b >/dev/null 2> /dev/null
fi
UUID='';eval $(block info /dev/$b | grep -o -e "UUID=\S*")
if [ ! "$UUID" ] ; then
log "获取/dev/$b设备UUID信息失败"
expquit 1
else
log "获取/dev/$b设备UUID信息:$UUID成功"
fi
case "$target_function" in
"/overlay")
if [ "$keep_config" = "1" ] ; then
# cp -a -f /overlay/* /mnt/$b/ || cp -a -f /rom/overlay/* /mnt/$b/
tar -C /overlay -cvf - . | tar -C /mnt/$b/ -xf - || tar -C /rom/overlay -cvf - . | tar -C /mnt/$b/ -xf -
umount /dev/$b >/dev/null 2> /dev/null
[ $? -ne 0 ] && umount /mnt/$b >/dev/null 2> /dev/null
[ $? -ne 0 ] && block umount /dev/$b >/dev/null 2> /dev/null
block detect > /etc/config/fstab
OVERLAY=`uci -q get fstab.@mount[0].target `
if [ "$OVERLAY" == "/overlay" -o "$OVERLAY" == "/dev/loop0" ] ;then
uci -q set fstab.@mount[0].uuid="${UUID}"
uci -q set fstab.@mount[0].target='/overlay'
uci -q set fstab.@mount[0].enabled='0'
fi
msum=$(grep -c "'mount'" /etc/config/fstab)
for i in $(seq 0 $((msum-1)))
do
zuuid=`uci -q get fstab.@mount[$i].uuid `
[ $? -ne 0 ] && break
if [ "$zuuid" = "$UUID" ] ; then
uci -q set fstab.@mount[$i].target="/overlay"
uci -q set fstab.@mount[$i].enabled='1'
fi
done
uci set fstab.@global[0].delay_root="15"
uci commit fstab
log "保留数据overlay扩展/dev/$b成功"
sleep 3
log "设备重启才能生效"
expquit 2
else
umount /dev/$b >/dev/null 2> /dev/null
[ $? -ne 0 ] && umount /mnt/$b >/dev/null 2> /dev/null
[ $? -ne 0 ] && block umount /dev/$b >/dev/null 2> /dev/null
block detect > /etc/config/fstab
OVERLAY=`uci -q get fstab.@mount[0].target `
if [ "$OVERLAY" == "/overlay" -o "$OVERLAY" == "/dev/loop0" ] ;then
uci -q set fstab.@mount[0].uuid="${UUID}"
uci -q set fstab.@mount[0].target='/overlay'
uci -q set fstab.@mount[0].enabled='0'
fi
msum=$(grep -c "'mount'" /etc/config/fstab)
for i in $(seq 0 $((msum-1)))
do
zuuid=`uci -q get fstab.@mount[$i].uuid `
[ $? -ne 0 ] && break
if [ "$zuuid" = "$UUID" ] ; then
uci -q set fstab.@mount[$i].target="/overlay"
uci -q set fstab.@mount[$i].enabled='1'
fi
done
uci set fstab.@global[0].delay_root="15"
uci commit fstab
log "不保留数据overlay扩展/dev/$b成功"
sleep 3
log "设备重启才能生效"
expquit 2
fi
;;
"/opt")
umount /dev/$b >/dev/null 2> /dev/null
[ $? -ne 0 ] && umount /mnt/$b >/dev/null 2> /dev/null
[ $? -ne 0 ] && block umount /dev/$b >/dev/null 2> /dev/null
for OPT in $(mount |grep /opt | awk '{print $1}');do
umount $OPT >/dev/null 2> /dev/null
log "取消/opt之前的挂载$OPT成功"
done
block detect > /etc/config/fstab
mkdir -p $target_function
msum=$(grep -c "'mount'" /etc/config/fstab)
mount_device /dev/$b "$target_function"
for i in $(seq 0 $((msum-1)))
do
zuuid=`uci -q get fstab.@mount[$i].uuid `
[ $? -ne 0 ] && break
if [ "$zuuid" = "$UUID" ] ; then
uci -q set fstab.@mount[$i].target="$target_function"
uci -q set fstab.@mount[$i].enabled='1'
fi
done
uci commit fstab
# ln -sf /mnt/$b /overlay
if is_disk_mounted "/opt"; then
log "/dev/$b分区扩容和挂载到$target_function成功"
log "如果没生效,请重启设备"
expquit 2
else
log "/dev/$b分区扩容和挂载到$target_function失败"
fi
;;
"/")
if [ "$keep_config" = "1" ] ; then
mkdir -p /tmp/introot
mount --bind / /tmp/introot
tar -C /tmp/introot -cvf - . | tar -C /mnt/$b -xf -
umount /tmp/introot || block umount /tmp/introot
umount /dev/$b >/dev/null 2> /dev/null
[ $? -ne 0 ] && umount /mnt/$b >/dev/null 2> /dev/null
[ $? -ne 0 ] && block umount /dev/$b >/dev/null 2> /dev/null
block detect > /etc/config/fstab
OVERLAY=`uci -q get fstab.@mount[0].target `
if [ "$OVERLAY" == "/overlay" -o "$OVERLAY" == "/dev/loop0" ] ;then
uci -q set fstab.@mount[0].uuid="${UUID}"
uci -q set fstab.@mount[0].target='/'
uci -q set fstab.@mount[0].enabled='1'
fi
log "保留数据根目录扩展/dev/$b成功"
sleep 3
log "设备重启才能生效"
expquit 2
else
mkdir -p /tmp/introot
mount --bind / /tmp/introot
umount /tmp/introot || block umount /tmp/introot
umount /dev/$b >/dev/null 2> /dev/null
[ $? -ne 0 ] && umount /mnt/$b >/dev/null 2> /dev/null
[ $? -ne 0 ] && block umount /dev/$b >/dev/null 2> /dev/null
block detect > /etc/config/fstab
OVERLAY=`uci -q get fstab.@mount[0].target `
if [ "$OVERLAY" == "/overlay" -o "$OVERLAY" == "/dev/loop0" ] ;then
uci -q set fstab.@mount[0].uuid="${UUID}"
uci -q set fstab.@mount[0].target='/'
uci -q set fstab.@mount[0].enabled='1'
fi
log "保留数据根目录扩展/dev/$b成功"
sleep 3
log "设备重启才能生效"
expquit 2
fi
;;
*)
umount /dev/$b >/dev/null 2> /dev/null
[ $? -ne 0 ] && umount /mnt/$b >/dev/null 2> /dev/null
[ $? -ne 0 ] && block umount /dev/$b >/dev/null 2> /dev/null
block detect > /etc/config/fstab
mkdir -p $target_function
msum=$(grep -c "'mount'" /etc/config/fstab)
mount_device /dev/$b /mnt/$b
for i in $(seq 0 $((msum-1)))
do
zuuid=`uci -q get fstab.@mount[$i].uuid `
[ $? -ne 0 ] && break
if [ "$zuuid" = "$UUID" ] ; then
uci -q set fstab.@mount[$i].target="/mnt/$b"
uci -q set fstab.@mount[$i].enabled='1'
fi
done
uci commit fstab
if is_disk_mounted /mnt/$b ; then
log "/dev/$b分区扩容和挂载到/mnt/$b成功"
log "如果没生效,请重启设备"
expquit 2
else
log "/dev/$b分区扩容和挂载到/mnt/$b失败"
fi
;;
esac
}
get_system_disk() {
SYSTEM_DISK=$( df -h | grep boot |awk -F ' ' '{print $1}' |head -1)
[ -z ${SYSTEM_DISK} ] && SYSTEM_DISK=$(mount | grep 'on /overlay' | awk '{print $1}' | sed 's/[0-9]*$//' |head -1)
echo "$SYSTEM_DISK"
}
get_all_disks() {
DISKS=`find /dev -regex '.*/\(sd[a-z]\|mmcblk[0-9]\+\|sata[a-z]\|nvme[0-9]\+n[0-9]\+\|vd[a-z]\)$'`
echo "$DISKS"
}
check_free_space() {
DISK=$1
PARTED_OUTPUT=$(parted /dev/$DISK unit GB print free 2>/dev/null)
FREE_SPACE=$(echo "$PARTED_OUTPUT" | grep "Free Space" | awk '{print $3}' )
echo $FREE_SPACE |awk -F '.' '{print $1}'
}
# 获取下一个新的可用的分区号
get_next_partition_number() {
DISK=$1
PARTITIONS=$(fdisk -l /dev/$DISK 2>/dev/null | grep -v boot | grep -E "^/dev/$DISK" | awk '{print $1}' | sed 's/\/dev\/[a-z]*//g' | awk -F '[^0-9]+' '{print $NF}')
MAX_PARTITION=$(echo "$PARTITIONS" | sort -n | tail -n 1)
NEXT_PARTITION=$(awk -v n="$MAX_PARTITION" 'BEGIN { print n + 1 }')
#NEXT_PARTITION=$((MAX_PARTITION + 1))
echo "$NEXT_PARTITION"
}
# 获取最后一个可用的分区号
get_last_partition_number() {
DISK=$1
PARTITIONS=$(fdisk -l /dev/$DISK 2>/dev/null | grep -v boot | grep -E "^/dev/$DISK" | awk '{print $1}' | sed 's/\/dev\/[a-z]*//g' | awk -F '[^0-9]+' '{print $NF}')
MAX_PARTITION=$(echo "$PARTITIONS" | sort -n | tail -n 1)
echo "$MAX_PARTITION"
}
# 获取硬盘分区数
get_partition_number() {
DISK=$1
PARTITIONS=$(fdisk -l /dev/$DISK 2>/dev/null | grep -v boot | grep -E "^/dev/$DISK" | awk '{print $1}' | sed 's/\/dev\/[a-z]*//g' | wc -l)
echo "$PARTITIONS"
}
get_config() {
config_get target_function $1 target_function 1
config_get target_disk $1 target_disk 1
config_get_bool keep_config $1 keep_config 1
config_get format_type $1 format_type
}
autopart() {
#config_load partexp
#config_foreach get_config global
touch $LOCK
init_env
gen_log
target_function=$( _uci_get target_function "/opt" )
format_type=$( _uci_get format_type)
DISK=$( _uci_get target_disk "/sda3" )
keep_config=$( _uci_get keep_config "1" )
NEXTPART=1 #目标分区
DISKSALL=$(get_all_disks) #硬盘名列表
DISK_COUNT=$(echo "$DISKSALL" | wc -l) #所有硬盘数量
log "系统中检测到的硬盘数量: $DISK_COUNT"
log "硬盘信息列表:" $DISKSALL
SYSTEM_DISK=$(get_system_disk)
log "系统盘: "$SYSTEM_DISK
if [ "/dev/$DISK" == "$SYSTEM_DISK" ] ;then
fdisksave /dev/$DISK
log "此次执行操作功能:$target_function ,目标盘是系统盘:/dev/$DISK"
PARTITIONSUM=$(get_partition_number $DISK)
log "目标盘 $DISK 一共有分区数: $PARTITIONSUM个"
if [[ "$PARTITIONSUM" -gt 3 ]];then
FREE_SPACE=$(check_free_space $(basename $DISK))
log "目标盘 $DISK 有剩余空间: $FREE_SPACE Gb"
if [[ "$FREE_SPACE" -gt 2 ]]; then
NEXTPART=$(get_next_partition_number $DISK)
else
NEXTPART=$(get_last_partition_number $DISK)
fi
else
FREE_SPACE=$(check_free_space $(basename $DISK))
log "目标盘 $DISK 有剩余空间: $FREE_SPACE Gb"
if [[ "$FREE_SPACE" -gt 2 ]]; then
NEXTPART=$(get_next_partition_number $DISK)
else
log "目标盘 $SYSTEM_DISK 没有足够的剩余空间!"
expquit 1
fi
fi
else
log "此次执行操作功能:$target_function ,目标盘是:/dev/$DISK"
PARTITIONSUM=$(get_partition_number $DISK)
log "目标盘 $DISK 一共有分区数: $PARTITIONSUM个"
if [[ "$PARTITIONSUM" -gt 1 ]];then
FREE_SPACE=$(check_free_space $(basename $DISK))
log "目标盘 $DISK 有剩余空间: $FREE_SPACE Gb"
[[ $FREE_SPACE -gt 2 ]] && NEXTPART=$(get_next_partition_number $DISK) || NEXTPART=$(get_last_partition_number $DISK)
else
NEXTPART=1
fi
fi
log "定位到操作目标设备分区:/dev/$DISK$NEXTPART"
case "$DISK" in
vd*) fdiskB $NEXTPART;;
sd*) fdiskB $NEXTPART;;
nvme*) fdiskB p$NEXTPART;;
mmc*) fdiskB p$NEXTPART;;
*)
log "目标设备/dev/$DISK暂不支持请联系作者sirpdboy"
;;
esac
expquit 1
}
start() {
[ -f $LOCK ] && exit
[ x$xBOOT = x1 ] || autopart
rm -f $LOCK 2>/dev/null
}
boot() {
xBOOT=1
}
expquit() {
rm -f $LOCK
uci_set fstab @global[0] anon_mount '1'
uci_set fstab @global[0] auto_mount '1'
[ -e "/etc/config/dockerd" ] && /etc/init.d/dockerd restart >/dev/null 2> /dev/null
sleep 2
[ $1 == 2 ] && log "重启中...\n" &&reboot
exit $1
}

View File

@ -1,517 +0,0 @@
#!/bin/sh /etc/rc.common
#
# Copyright (C) 2021-2022 sirpdboy <herboy2008@gmail.com> https://github.com/sirpdboy/partexp
# This is free software, licensed under the Apache License, Version 2.0 .
#
START=99
USE_PROCD=1
EXTRA_COMMANDS="autopart"
LOCK=/var/lock/partexp.lock
LOGD=/etc/partexp
LOG=/etc/partexp/partexp.log
limit_log() {
local logf=$1
[ ! -f "$logf" ] && return
local sc=100
[ -n "$2" ] && sc=$2
local count=$(grep -c "" $logf)
if [[ $count -gt $sc ]];then
let count=count-$sc
sed -i "1,$count d" $logf
fi
}
init_env() {
[ -d "$LOGD" ] || mkdir -p $LOGD
[ ! -f "$LOG" ] && echo " " > $LOG
}
gen_log()(
log "---------------自动分区扩展挂载开始执行------------------ "
)
log(){
echo -e " $(date +'%Y-%m-%d %H:%M:%S') $*"
}
get_config() {
config_get target_function $1 target_function 1
config_get target_disk $1 target_disk 1
config_get_bool keep_config $1 keep_config 1
config_get_bool auto_format $1 auto_format 1
}
# 定义函数:检查硬盘是否已挂载
is_disk_mounted() {
DISK=$1
# 检查是否已挂载
if mount | grep -q "^/dev/$DISK"; then
return 0 # 已挂载
else
return 1 # 未挂载
fi
}
# 定义函数:取消挂载硬盘
unmount_disk() {
DISK=$1
# log "正在取消挂载 /dev/$DISK..."
MOUNT='';eval $(block info "/dev/$DISK" | grep -o -e "MOUNT=\S*")
if [ "$MOUNT" ] ; then
umount /dev/$DISK 2>/dev/null
if [ $? -eq 0 ]; then
log "取消挂载成功: /dev/$DISK"
else
log "取消挂载失败: /dev/$DISK"
fi
fi
}
# 定义函数:检查是否有共享挂载(如 Samba 或 NFS
check_shared_mount() {
DISK=$1
if [ -f /etc/config/samba ]; then
SHARED=$(grep -q "/dev/$DISK" /etc/config/samba)
if [ $? -eq 0 ]; then
log "检测到 Samba 共享挂载: /dev/$DISK"
return 0
fi
fi
# 检查是否有 NFS 共享
if [ -f /etc/exports ]; then
SHARED=$(grep -q "/dev/$DISK" /etc/exports)
if [ $? -eq 0 ]; then
log "检测到 NFS 共享挂载: /dev/$DISK"
return 0
fi
fi
return 1
}
usamba(){
s=$1
s2=$2
[ -e "/etc/config/$s" ] && {
msum=$(grep -c "config sambashare" /etc/config/$s)
for i in $(seq 0 $((msum)))
do
pdev=`uci -q get $s.@sambashare[$i].path `
[ "$pdev" = "$s2" ] && {
uci delete $s.@sambashare[$i]
uci commit $s
log "分区/dev/$b被挂载$MOUNT共享使用删除$s共享成功"
sleep 1
}
done
}
# 取消 Samba 共享
if [ -f /etc/config/$s ]; then
sed -i "/\/dev\/$b/d" /etc/config/$s
/etc/init.d/$s restart
fi
# 取消 NFS 共享
if [ -f /etc/exports ]; then
sed -i "/\/dev\/$b/d" /etc/exports
/etc/init.d/nfs restart
fi
}
is_disk_partitioned() {
PARTITION_COUNT=$(fdisk -l /dev/$1 2>/dev/null | grep -E "^/dev/$2" | wc -l)
if [[ "$PARTITION_COUNT" -gt 0 ]]; then
echo 1
else
echo 0
fi
}
partednew(){
DISK=$1
parted -s /dev/$DISK mklabel gpt
parted -s /dev/$DISK mkpart primary ext4 1MiB -1
}
fdisknew(){
echo -e "n\np\n\n\n\nw" | fdisk /dev/$1 >/dev/null 2> /dev/null
}
fdisksave(){
echo -e "n\w" | fdisk /dev/$1 >/dev/null 2> /dev/null
}
fdiskB(){
a=$1
b=$1$2
log "检测$a是否分区$b..."
isfdisk=0
isP=$(is_disk_partitioned $a $b)
if [ "$isP" == '0' ] ;then
fdisksave $a
fdisknew $a
sleep 2
isfdisk=1
fi
isP=$(is_disk_partitioned $a $b)
if [ $isP == '1' -a "$isfdisk" == 1 ] ;then
log "分区$b建立成功"
elif [ $isP == '1' -a "$isfdisk" = 0 ] ;then
log "检测目标分区$b已存在."
else
log "分区$b建立失败没有足够的空间操作失败"
expquit 1
fi
sleep 1
[ -e "/etc/config/dockerd" ] && /etc/init.d/dockerd stop >/dev/null 2> /dev/null
block detect > /etc/config/fstab
isD=` block info "/dev/$b" `
if [ "$isD" ];then
MOUNT='';eval $(block info "/dev/$b" | grep -o -e "MOUNT=\S*")
log "检测/dev/$b是不是被共享..."
if [ "x$MOUNT" != 'x' ] ; then
usamba samba4 $MOUNT
usamba samba $MOUNT
sleep 5
umount $MOUNT || block umount /dev/$b >/dev/null 2> /dev/null
sleep 5
MOUNT='';eval $(block info "/dev/$b" | grep -o -e "MOUNT=\S*")
if [ "x$MOUNT" != 'x' ] ;then
log "分区/dev/$b挂载$MOUNT使用中,自动删除失败!请手动删除共享或者取消其它插件的占用权限再重试!"
expquit 1
fi
else
log "检测目标设备$b未被共享..."
fi
fi
#isD=`block info /dev/$b | awk -F 'TYPE=' '{print $2}'| sed 's,\",,g' `
TYPE='';eval $(block info "/dev/$b" | grep -o -e "TYPE=\S*")
if [ "$target_function" = "/" -o "$target_function" = "/overlay" ] ; then
log "正在将/dev/$b格式化为EXT4文件系统..."
mkfs.ext4 -L extroot /dev/$b >/dev/null 2> /dev/null
log "设备/dev/$b格式化EXT4成功"
elif [ "$auto_format" = "1" -o "$isfdisk" = "1" ] ; then
mkfs.ext4 -F /dev/$b >/dev/null 2> /dev/null
log "设备/dev/$b格式化EXT4成功"
elif [ "$TYPE" ];then
log "设备/dev/$b无需格式化"
else
log "设备/dev/$b未格式化无法正常使用"
expquit 1
fi
[ -d "/mnt/$b" ] || mkdir -p /mnt/$b
MOUNT='';eval $(block info "/dev/$b" | grep -o -e "MOUNT=\S*")
if [ "x$MOUNT" != 'x' ] ;then
umount /mnt/$b || block umount /dev/$b >/dev/null 2> /dev/null
MOUNT='';eval $(block info "/dev/$b" | grep -o -e "MOUNT=\S*")
if [ "$MOUNT" ] ; then
log "检测设备/dev/$b被占用,请检查设备硬件或中止其他插件等占用权限再重试!"
expquit 1
fi
fi
TYPE='';eval $(block info "/dev/$b" | grep -o -e "TYPE=\S*")
if [ "$TYPE" = "ntfs" ];then
log "检测设备/dev/$b分区是$TYPE格式"
if [ `which ntfs-3g ` ] ;then
mount -t ntfs-3g /dev/$b /mnt/$b >/dev/null 2> /dev/null
elif [ `which ntfs3 ` ] ;then
mount -t ntfs3 /dev/$b /mnt/$b >/dev/null 2> /dev/null
else
log "不支持NTFS分区挂载请安装ntfs-3g或者ntfs3支持服务"
expquit 1
fi
else
/usr/bin/mount /dev/$b /mnt/$b >/dev/null 2> /dev/null
fi
UUID='';eval $(block info /dev/$b | grep -o -e "UUID=\S*")
if [ ! "$UUID" ] ; then
log "获取/dev/$b设备UUID信息失败"
expquit 1
else
log "获取/dev/$b设备UUID信息:$UUID成功"
fi
if [ "$target_function" = "/" ] ; then
if [ "$keep_config" = "1" ] ; then
mkdir -p /tmp/introot
mount --bind / /tmp/introot
tar -C /tmp/introot -cvf - . | tar -C /mnt/$b -xf -
umount /tmp/introot || block umount /tmp/introot
umount /mnt/$b || block umount /dev/$b >/dev/null 2> /dev/null
block detect > /etc/config/fstab
OVERLAY=`uci -q get fstab.@mount[0].target `
if [ "$OVERLAY" == "/overlay" -o "$OVERLAY" == "/dev/loop0" ] ;then
uci -q set fstab.@mount[0].uuid="${UUID}"
uci -q set fstab.@mount[0].target='/'
uci -q set fstab.@mount[0].enabled='1'
fi
log "保留数据根目录扩展/dev/$b成功"
sleep 5
log "设备重启才能生效"
expquit 2
else
mkdir -p /tmp/introot
mount --bind / /tmp/introot
umount /tmp/introot || block umount /tmp/introot
umount /mnt/$b || block umount /dev/$b >/dev/null 2> /dev/null
block detect > /etc/config/fstab
OVERLAY=`uci -q get fstab.@mount[0].target `
if [ "$OVERLAY" == "/overlay" -o "$OVERLAY" == "/dev/loop0" ] ;then
uci -q set fstab.@mount[0].uuid="${UUID}"
uci -q set fstab.@mount[0].target='/'
uci -q set fstab.@mount[0].enabled='1'
fi
log "保留数据根目录扩展/dev/$b成功"
sleep 5
log "设备重启才能生效"
expquit 2
fi
elif [ "$target_function" = "/overlay" ] ; then
if [ "$keep_config" = "1" ] ; then
# cp -a -f /overlay/* /mnt/$b/ || cp -a -f /rom/overlay/* /mnt/$b/
tar -C /overlay -cvf - . | tar -C /mnt/$b/ -xf - || tar -C /rom/overlay -cvf - . | tar -C /mnt/$b/ -xf -
umount /mnt/$b || block umount /dev/$b >/dev/null 2> /dev/null
block detect > /etc/config/fstab
OVERLAY=`uci -q get fstab.@mount[0].target `
if [ "$OVERLAY" == "/overlay" -o "$OVERLAY" == "/dev/loop0" ] ;then
uci -q set fstab.@mount[0].uuid="${UUID}"
uci -q set fstab.@mount[0].target='/overlay'
uci -q set fstab.@mount[0].enabled='0'
fi
msum=$(grep -c "'mount'" /etc/config/fstab)
for i in $(seq 0 $((msum-1)))
do
zuuid=`uci -q get fstab.@mount[$i].uuid `
[ $? -ne 0 ] && break
if [ "$zuuid" = "$UUID" ] ; then
uci -q set fstab.@mount[$i].target="/overlay"
uci -q set fstab.@mount[$i].enabled='1'
fi
done
uci set fstab.@global[0].delay_root="15"
uci commit fstab
log "保留数据overlay扩展/dev/$b成功"
sleep 5
log "设备重启才能生效"
expquit 2
else
umount /mnt/$b || block umount /dev/$b >/dev/null 2> /dev/null
block detect > /etc/config/fstab
OVERLAY=`uci -q get fstab.@mount[0].target `
if [ "$OVERLAY" == "/overlay" -o "$OVERLAY" == "/dev/loop0" ] ;then
uci -q set fstab.@mount[0].uuid="${UUID}"
uci -q set fstab.@mount[0].target='/overlay'
uci -q set fstab.@mount[0].enabled='0'
fi
msum=$(grep -c "'mount'" /etc/config/fstab)
for i in $(seq 0 $((msum-1)))
do
zuuid=`uci -q get fstab.@mount[$i].uuid `
[ $? -ne 0 ] && break
if [ "$zuuid" = "$UUID" ] ; then
uci -q set fstab.@mount[$i].target="/overlay"
uci -q set fstab.@mount[$i].enabled='1'
fi
done
uci set fstab.@global[0].delay_root="15"
uci commit fstab
log "不保留数据overlay扩展/dev/$b成功"
sleep 3
log "设备重启才能生效"
expquit 2
fi
elif [ "$target_function" = "/lnoverlay" ] ; then
umount /mnt/$b || block umount /dev/$b >/dev/null 2> /dev/null
block detect > /etc/config/fstab
mkdir -p $target_function
msum=$(grep -c "'mount'" /etc/config/fstab)
for i in $(seq 0 $((msum-1)))
do
zuuid=`uci -q get fstab.@mount[$i].uuid `
[ $? -ne 0 ] && break
if [ "$zuuid" = "$UUID" ] ; then
uci -q set fstab.@mount[$i].target="/mnt/$b"
uci -q set fstab.@mount[$i].enabled='1'
fi
done
uci commit fstab
ln -sf /mnt/$b /overlay
log "设备/dev/$b挂载/mnt/$b软链到/overlay扩容成功"
log "设备重启才能生效"
expquit 2
else
umount /mnt/$b || block umount /dev/$b >/dev/null 2> /dev/null
block detect > /etc/config/fstab
mkdir -p $target_function
msum=$(grep -c "'mount'" /etc/config/fstab)
for i in $(seq 0 $((msum-1)))
do
zuuid=`uci -q get fstab.@mount[$i].uuid `
[ $? -ne 0 ] && break
if [ "$zuuid" = "$UUID" ] ; then
[ "$target_function" = "/opt" ] && uci -q set fstab.@mount[$i].target="$target_function" || uci -q set fstab.@mount[$i].target="/mnt/$b"
uci -q set fstab.@mount[$i].enabled='1'
fi
done
uci commit fstab
[ "$target_function" = "/opt" ] && log "挂载/dev/$b到$target_function成功" || log "挂载/dev/$b到/mnt/$b成功"
log "设备重启才能生效"
expquit 2
fi
}
get_system_disk() {
SYSTEM_DISK=$(mount | grep 'on /overlay' | awk '{print $1}' | sed 's/[0-9]*$//' |head -1)
[ -z ${SYSTEM_DISK} ] && SYSTEM_DISK=$( df -h | grep boot |awk -F ' ' '{print $1}' |head -1)
echo "$SYSTEM_DISK"
}
get_all_disks() {
DISKS=`find /dev -regex '.*/\(sd[a-z]\|mmcblk[0-9]\+\|sata[a-z]\|nvme[0-9]\+n[0-9]\+\|vd[a-z]\)$'`
echo "$DISKS"
}
check_free_space() {
DISK=$1
PARTED_OUTPUT=$(parted /dev/$DISK unit GB print free 2>/dev/null)
FREE_SPACE=$(echo "$PARTED_OUTPUT" | grep "Free Space" | awk '{print $3}' )
echo $FREE_SPACE |awk -F '.' '{print $1}'
}
# 定义函数:获取下一个新的可用的分区号
get_next_partition_number() {
DISK=$1
PARTITIONS=$(fdisk -l /dev/$DISK 2>/dev/null | grep -v boot | grep -E "^/dev/$DISK" | awk '{print $1}' | sed 's/\/dev\/[a-z]*//g' | awk -F '[^0-9]+' '{print $NF}')
MAX_PARTITION=$(echo "$PARTITIONS" | sort -n | tail -n 1)
NEXT_PARTITION=$(awk -v n="$MAX_PARTITION" 'BEGIN { print n + 1 }')
#NEXT_PARTITION=$((MAX_PARTITION + 1))
echo "$NEXT_PARTITION"
}
# 定义函数:获取最后一个可用的分区号
get_last_partition_number() {
DISK=$1
PARTITIONS=$(fdisk -l /dev/$DISK 2>/dev/null | grep -v boot | grep -E "^/dev/$DISK" | awk '{print $1}' | sed 's/\/dev\/[a-z]*//g' | awk -F '[^0-9]+' '{print $NF}')
MAX_PARTITION=$(echo "$PARTITIONS" | sort -n | tail -n 1)
echo "$MAX_PARTITION"
}
# 定义函数:获取硬盘分区数
get_partition_number() {
DISK=$1
PARTITIONS=$(fdisk -l /dev/$DISK 2>/dev/null | grep -v boot | grep -E "^/dev/$DISK" | awk '{print $1}' | sed 's/\/dev\/[a-z]*//g' | wc -l)
echo "$PARTITIONS"
}
autopart() {
config_load partexp
config_foreach get_config global
init_env
gen_log
NEXTPART=1 #目标分区
DISK=$target_disk #目标硬盘
DISKSALL=$(get_all_disks) #硬盘名列表
DISK_COUNT=$(echo "$DISKSALL" | wc -l) #所有硬盘数量
log "系统中检测到的硬盘数量: $DISK_COUNT"
log "硬盘信息列表:" $DISKSALL
SYSTEM_DISK=$(get_system_disk)
log "系统盘: "$SYSTEM_DISK
if [ "/dev/$DISK" == "$SYSTEM_DISK" ] ;then
fdisksave /dev/$DISK
log "此次执行操作功能:$target_function ,目标盘是系统盘:/dev/$DISK"
PARTITIONSUM=$(get_partition_number $DISK)
log "目标盘 $DISK 一共有分区数: $PARTITIONSUM个"
if [[ "$PARTITIONSUM" -gt 3 ]];then
FREE_SPACE=$(check_free_space $(basename $DISK))
log "目标盘 $DISK 有剩余空间: $FREE_SPACE Gb"
if [[ "$FREE_SPACE" -gt 2 ]]; then
NEXTPART=$(get_next_partition_number $DISK)
else
NEXTPART=$(get_last_partition_number $DISK)
fi
else
FREE_SPACE=$(check_free_space $(basename $DISK))
log "目标盘 $DISK 有剩余空间: $FREE_SPACE Gb"
if [[ "$FREE_SPACE" -gt 2 ]]; then
NEXTPART=$(get_next_partition_number $DISK)
else
log "目标盘 $SYSTEM_DISK 没有足够的剩余空间!"
expquit 1
fi
fi
else
log "此次执行操作功能:$target_function ,目标盘是:/dev/$DISK"
PARTITIONSUM=$(get_partition_number $DISK)
log "目标盘 $DISK 一共有分区数: $PARTITIONSUM个"
if [[ "$PARTITIONSUM" -gt 1 ]];then
FREE_SPACE=$(check_free_space $(basename $DISK))
log "目标盘 $DISK 有剩余空间: $FREE_SPACE Gb"
[[ $FREE_SPACE -gt 2 ]] && NEXTPART=$(get_next_partition_number $DISK) || NEXTPART=$(get_last_partition_number $DISK)
else
NEXTPART=1
fi
fi
log "定位到操作目标设备分区:/dev/$DISK$NEXTPART"
case "$DISK" in
vd*) fdiskB $DISK $NEXTPART;;
sd*) fdiskB $DISK $NEXTPART;;
nvme*) fdiskB $DISK p$NEXTPART;;
mmc*) fdiskB $DISK p$NEXTPART;;
*)
log "目标设备/dev/$target_disk暂不支持请联系作者sirpdboy"
expquit 1
;;
esac
rm -f $LOCK
}
start() {
[ x$x = x1 ] && exit || autopart
}
boot() {
x=1
}
expquit() {
rm -f $LOCK
[ -e "/etc/config/dockerd" ] && /etc/init.d/dockerd restart >/dev/null 2> /dev/null
sleep 5
[ $1 == 2 ] && log "重启中...\n" &&reboot
exit $1
}