-
Notifications
You must be signed in to change notification settings - Fork 1
/
partgrator-pre
318 lines (225 loc) · 9.69 KB
/
partgrator-pre
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
#!/bin/sh
# partgrator-pre version 1.0.0
#
# partgrator-pre truncates logfiles, cleans mountpoints, and wraps disk-check tools
#
# For more information, issues, or assistance visit: https://github.com/caribpa/partgrator
#
# Author: caribpa (https://github.com/caribpa)
#
# Copyright 2020 caribpa
#
# partgrator-pre is free to use under the Artistic License 2.0
#
# Find the Artistic License 2.0 here: https://spdx.org/licenses/Artistic-2.0.html
########### USER VARIABLES ###########
partgrator_dir="/jffs/addons/partgrator" # Partgrator installation directory path
logfile_truncate_lines=500 # Lines to remain on ${logfile} after being truncated
logfile_truncate_minutes=30 # Minutes for truncating ${logfile} since last modification
process_tools="e2fsck" # disk-check tools whose return code will be processed by
# partgrator and a migration will be scheduled if needed
# Note that the tool name can only contain characters
# considered valid as function names
mount_folder="/tmp/mnt" # Absolute path to the folder where the partitions are
# automatically mounted
######################################
### ####
### USERS DO NOT NEED TO MODIFY ####
### BELOW THIS POINT ####
### ####
######################################
######### GENERAL VARIABLES ##########
tools_needed="[
awk
blkid
date
echo
expr
false
grep
rm
sed
rmdir
tail
type
wc
${process_tools}"
########### SOURCE INCLUDE ###########
log_tag="partgrator-pre" # Tag used as prefix when logging messages
helpers_tools_check="no"
. "${partgrator_dir}/helpers"
logfile_last_modified="$(LC_ALL=C ; \
PATH=/sbin:/bin:/usr/sbin:/usr/bin ; \
date -r "${logfile}" +%s 2> /dev/null )"
helpers_tools_check="yes"
check_helpers_tools || exit $?
########### PREREQUISITES ############
log_msg "Initializing partgrator-pre script"
check_tools "${tools_needed}" \
\
\
&& ( # Beginning of main subshell - Beginning of check_tools conditional execution
########### SHELL VARIABLES ##########
LC_ALL=C
PATH=/sbin:/bin:/usr/sbin:/usr/bin
########## GLOBAL VARIABLES ##########
partition="$1"
filesystem="$2"
############## HELPERS ###############
truncate_logfile() {
local current_time="$(awk 'BEGIN{srand(); print srand()}')" || return $?
local logfile_current_lines="$(wc -l "${logfile}")" || return $?
local seconds_difference=$(expr ${current_time} - ${logfile_last_modified:-0})
local ret_code=0
if [ -n "${logfile_last_modified}" ] \
&& [ -n "${logfile_truncate_minutes}" ] \
&& [ ${seconds_difference#-} -gt $((logfile_truncate_minutes \* 60)) ] \
&& [ ${logfile_truncate_lines} -le ${logfile_current_lines%% *} ]
then
log_msg "Truncating logfile ${logfile} to the last" \
"${logfile_truncate_lines} lines"
echo "$(tail -n -${logfile_truncate_lines} "${logfile}")" > "${logfile}"
ret_code=$?
if [ ${ret_code} -ne 0 ]; then
log_msg -p error "echo failed with error code ${ret_code} when" \
"truncating ${logfile}"
else
log_msg "${logfile} truncated successfully"
fi
fi
return ${ret_code}
}
# Automatically remove previously existing mountpoint folders
clean_partition_mountpoint() {
local partition="$1"
local label=''
local mountpoint=''
local mountpoints=''
local ret_code=0
label="$(get_partition_label "${partition}")" || return $?
log_msg "Starting partition mountpoint cleaner"
mountpoint="${mount_folder}/${label//[ \"\']/_}" # Replace problematic symbols
mountpoints="${mountpoint}*" # Shell expansion for-loop
log_msg "Checking if ${partition} mountpoint (${mountpoint})" \
"needs to be cleaned before being mounted"
if grep -q "^${partition} " "${mtab}"; then
log_msg -p warning "${partition} seems to be mounted"
log_msg -p warning "Not cleaning ${mountpoint} folder"
return 0
fi
# The shell expansion is needed to catch folders with numbers prefixed due to
# bad unmounting or missed cleanup
for mountpoint in ${mountpoints}; do
if [ -d "${mountpoint}" ] \
&& ! grep -q " ${mountpoint} " "${mtab}"
then
log_msg "Cleaning ${mountpoint}"
rm -f -- "${mountpoint}/.autocreated-dir"
rmdir -- "${mountpoint}"
ret_code=$?
if [ ${ret_code} -eq 0 ]; then
log_msg "${mountpoint} was successfully cleaned"
else
log_msg -p error "rmdir failed with error code ${ret_code}" \
"when trying to remove ${mountpoint}"
log_msg -p warning "Continuing without cleaning the" \
"previous mountpoint folder"
fi
fi
done
log_msg "Finishing partition mountpoint cleaner"
return ${ret_code}
}
############### MAIN #################
log_msg "Starting with ${partition} and ${filesystem} as parameters"
truncate_logfile
clean_partition_mountpoint "${partition}"
# End of main subshell - Comment redirection for debugging
) > /dev/null 2> /dev/null \
\
&& { # All the following will only be executed if the subshell succeeded
########## EXPORTED HELPERS ##########
override_tool() {
local tool_name="$1"
local tool_path="$(LC_ALL=C type "${tool_name}" 2>&1)"
local ret_code=0
log_msg "Overriding tool ${tool_name}"
if [ ! -e "${tool_path##* }" ]; then
log_msg -p error "Unable to override ${tool_name} as it${tool_path#${tool_name}}"
return 1
fi
tool_path="${tool_path##* }"
eval "${tool_name}"'() {
local params="$@"
local partition="${params##* }"
local file_content=""
local blkid_out=""
local label=""
local ret_code=0
# Return early if the partition is already mounted
grep -q "^${partition} " "'"${mtab}"'" && return 0
blkid_out="$(blkid "${partition}" 2> /dev/null)" || return $?
if expr "${blkid_out}" : "${partition}: LABEL=" > /dev/null; then
# Partition has a label
# Trim everything around the first and last double-quotes of the label
label="${blkid_out#*=\"}"
label="${label%\" *}"
else
# Partition has no label so assign as label the partition device
# (device name + partition number)
label="${partition##*\/}"
fi
# The tool should only be run for non-${partgrator_label} partitions
! case "${label}" in '"${partgrator_label}"'*) false;; esac \
|| '"${tool_path}"' ${params}
ret_code=$?
# Write the status only if a migration is not in progress
if [ ! -f "'"${migrating_file}"'" ]; then
# Delete the previous entry
[ -f "'"${partitions_status}"'" ] \
&& file_content="$(sed "/^"${partition//\//\\\/}" /d" \
"'"${partitions_status}"'" )"
# The newline can be used without a variable because of eval
echo "${file_content}${file_content:+'$'\n''}${partition}" \
"${ret_code}" \
":${label}" \
> "'"${partitions_status}"'"
fi
# Prematurely exit pre-mount for ${partgrator_label} partitions
[ "'"${partgrator_pre_mount}"'" = "0" ] \
&& ! case "${label}" in '"${partgrator_label}"'*) false;; esac \
&& exit ${ret_code}
return ${ret_code}
} '
ret_code=$?
if [ ${ret_code} -ne 0 ]; then
log_msg -p error "eval failed with error code ${ret_code} when" \
"trying to override tool ${tool_name}"
else
log_msg "Tool ${tool_name} was overridden successfully"
fi
return ${ret_code}
}
########### EXPORTED MAIN ############
log_msg "Starting overriding tools for processing" \
"their exit code when executed"
for tool in ${process_tools}; do
override_tool "${tool}"
done
log_msg "Finished overriding tools"
####### UNSET EXPORTED HELPERS #######
unset -f override_tool
} # End of the check_tools conditional execution
log_msg "Exiting"
####### UNSET GENERAL HELPERS ########
unset_helpers # log_tag and helpers_tools_check are unset here
###### UNSET GENERAL VARIABLES #######
unset -v tools_needed \
logfile_last_modified
######## UNSET USER VARIABLES ########
unset -v partgrator_dir \
logfile_truncate_lines \
logfile_truncate_minutes \
process_tools \
mount_folder
# EOF