群辉迁移套件后异常处理

迁移套件的存储空间,导致套件不可用,排查很久发现是一个简单的权限问题导致的
解决起来也很简单,不愿意的直接看结尾

前言

本来是从J1900换到J3455,但是sata接口少了两个,就临时全插上了

结果不知道sata转msata板子有什么毛病,重启过几次后,128g的msata盘直接g了,套件全无,不可写,但是重启又能恢复正常能读不能写

然后就想着干掉这个盘,换个新的sata固态上去,所以要迁移套件数据

迁移套件

本身这个盘是存储空间1,然后建了一个存储空间2来存放新的套件数据,直接找到网上一个现成的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#!/bin/bash

# v0.2
# 1、添加套件外部链接检测功能
# 提示:部分套件会链接到套件文件夹外部的文件(夹),迁移后一般还能正常运行,如果外部的文件(夹) 在需要调整的存储空间上,你可能需要手动移动它们,同时修改对应的软链接
# 2、增加显示特定存储空间上安装的套件清单功能
# 3、增加对迁移目标存储空间的检测

operation=$1


dir=("conf" "home" "store" "temp" "data")
link=("etc" "home" "target" "tmp" "var")


check_package () {
echo 正在检测套件是否含有外部链接...
check_result=0
for l in "${link[@]}";
do
if [ -e /var/packages/$package/$l ]
then
for f in `find /var/packages/$package/$l/ -type l`
do
#ll=$(ls -l $f)
#echo /${ll#*/}
local k=0
for ((j=0;j<=;j++))
do
if [ -e /var/packages/$package/${link[$j]} ]
then
lk=$(ls -l /var/packages/$package/${link[$j]})
# echo realpath1: `realpath -e --relative-base=${lk##* } $f`
# echo realpath2: `realpath -e $f`
if [ `realpath -e --relative-base=${lk##* } $f` = `realpath -e $f` ]
then
# echo realpath1=realpath2
((k=k+1))
else
# echo $f在${lk##* }目录下
break
fi
if [ $k -eq 5 ]
then
check_result=1
ll=$(ls -l $f)
echo 有外部链接:/${ll#*/}
fi
else
echo /var/packages/$package/${link[$j]} 不存在.
exit
fi

done

done
else
echo /var/packages/$package/$l 不存在.
exit
fi
done
if [ $check_result -eq 0 ]
then
echo 没有外部链接
fi
}

check_answer () {
local a=1
while [ $a -ne 0 ]
do
read -n1 -p "是否继续迁移套件$package?[y/n]" answer
case $answer in
Y|y)
a=0
echo;;
N|n)
echo
exit;;
esac
done
}

show_usage () {
echo "使用方法:
显示套件清单:
transferpackage.sh list [存储空间编号]
示例: transferpackage.sh list 显示所有安装的套件
transferpackage.sh list 2 显示所有安装在存储空间2上的套件
迁移套件:
transferpackage.sh transfer 套件名 目标存储空间编号
检查套件外部链接:
transferpackage.sh check 套件名
显示本帮助:
transferpackage.sh help"
}

case $operation in
list)
if [ $2 ]
then
synostgvolume --enum-dep-pkgs /volume$2
else
#package_list=$(ls /var/packages/ |tr -s " ")
echo " 套件名 -- 套件中心显示的名称
-----------------------------"
for a in `synopkg list --name`
do
if [ -e /var/packages/$a/INFO ]
then
package_name=$(cat /var/packages/$a/INFO | grep displayname_chs\= | grep -o '".*"' |sed 's/"//g')
if [ -z "$package_name" ]
then
package_name=$(cat /var/packages/$a/INFO | grep displayname\= | grep -o '".*"' |sed 's/"//g')
fi
echo $a -- $package_name
else
echo $a -- /var/packages/$a/INFO 文件不存在.该套件可能已卸载.
fi
done
fi
;;
transfer)
if [ ! $2 ];then show_usage;exit;fi
if [ ! $3 ];then show_usage;exit;fi
package=$2
new_volume=$3
# 检测目标存储空间
synostgvolume --is-writable /volume$new_volume 2>/dev/null
if [ $? -eq 255 ];then echo 错误:目标存储空间不可用;exit;fi
case `synopkg status $package | sed 's/^.*Status: \[//g' | sed 's/\].*//g'` in
0)
echo "检测到套件$package未停用,为避免出现未知错误建议先停用该套件再进行迁移."
check_answer
;;
255)
echo 套件$package未安装
exit;;
263)
#echo 套件$package已停用
;;
esac
# 检测外部链接
check_package
if [ $check_result -eq 1 ]
then
echo "套件$package存在以上外部链接,请根据需要手动迁移这些文件(夹)并修改相应链接."
check_answer
fi
for ((i=0;i<=4;i++))
do
if [ -e /var/packages/$package/${link[$i]} ]
then
lk=$(ls -l /var/packages/$package/${link[$i]})
original_lk=${lk##* }
original_volume=${original_lk:7:1}
if [ $new_volume -ne $original_volume ]
then
if [ ! -d /volume$new_volume/@app${dir[$i]} ]
then
mkdir /volume$new_volume/@app${dir[$i]}
if [ $? -eq 0 ];then echo -e "添加文件夹 /volume$new_volume/@app${dir[$i]}...\e[0;32m完成\e[0m.";else echo -e "添加文件夹 /volume$new_volume/@app${dir[$i]}...\e[0;31m失败\e[0m.";exit;fi
fi
new_lk=$original_lk
new_lk=${original_lk/$original_volume/$new_volume}
cp -a $original_lk $new_lk
if [ $? -eq 0 ];then echo -e "复制 $original_lk$new_lk...\e[0;32m完成\e[0m.";else echo -e "复制 $original_lk$new_lk...\e[0;31m失败\e[0m.";exit;fi
ln -snf $new_lk /var/packages/$package/${link[$i]}
if [ $? -eq 0 ];then echo -e "链接 $new_lk 到 /var/packages/$package/${link[$i]}...\e[0;32m完成\e[0m.";else echo -e "链接 $new_lk 到 /var/packages/$package/${link[$i]}...\e[0;31m失败\e[0m.";exit;fi
else
echo "目标存储空间与套件/var/packages/$package/${link[$i]}文件夹所在存储空间相同,无需迁移."
fi
else
echo "/var/packages/$package/${link[$i]} 不存在."
exit
fi
done
;;
check)
if [ ! $2 ];then show_usage;exit;fi
package=$2
check_package
;;
help|*)
show_usage
;;
esac

迁移了大部分套件没出现问题,最好的结果就是docker,photos都没问题,以为一切结束,都正常了,就把存储空间1噶了

套件异常

结果不正常的情况出现了,首先是Drive,一直提示需要启动Server,但是套件中心又显示是正常启动的,于是做了如下尝试

  1. 重新停用启用,无效

  2. 卸载套件重新装到存储空间2,无效

  3. 换个群辉型号,重新安装(不清除设置),无效

想了各种办法,包括:

  1. 网上的重建pgsql

  2. 装个其他套件刷新群辉配置

  3. 删除已有用户名和权限组,重新安装

均无效,我甚至把drive的sqlite数据库都给看遍了,没发现什么问题,找了几个小时的残留文件清理,重新安装还是无效

最后我还发现VideoStation也出现同样的问题,报错大致意思就是服务端不可用

但是有一个很奇怪的点在于,我把套件重新安装回存储空间1,它就一切正常了,于是我才去找了很久的残留和配置,怀疑是迁移脚本没覆盖到配置的修改

解决异常

我开始仔细分析日志,首先一个命令:

journalctl -u VideoStation.slice -f

这个可以观察VideoStation的所有服务的日志

然后发现一个可疑日志

没权限,然后找到对应的目录,给了777权限也没用

继续尝试,直接挂着这个命令,重新安装了一次套件,这次获取到了更详细的错误日志

这个就更明显了,说这个目录没有权限创建数据库,然后我就又给了777权限,还是没用

但是看了下父文件都是root的,也没去尝试改权限,这时我想到了是不是这个存储空间的权限问题,于是我把套件重新安装在了我另一个存储空间4

奇迹发生了,它运行正常了,那就代表了不是存储空间1的问题,就是存储空间2有问题,于是,我对比了两个存储空间的目录权限

关键的就是这几个目录的权限,这时我才反应过来,这不就是没执行和读权限吗?

于是很简单的命令就能解决了

1
chmod 755 \@appconf \@appdata \@apphome \@apptemp

然后只需要重新把套件装回存储空间2,一切ok

分析问题

最大的问题就是没下决心去看迁移套件的sh,不太确定它怎么处理的目录权限,所以才会没发现这么明显的问题,绕了太多弯路子,以为群辉的系统会配置的很复杂