Если вы хотите хранить образы дисков KVM/QEMU в неиспользуемых разделах, у вас есть несколько вариантов:
В любом случае вам понадобится создать новый пул хранения; что вы можете сделать с помощью virt-manager. Но варианты выше работают по-разному.
Подход на основе разделов на самом деле является вводящим в заблуждение названием. Вы могли бы подумать, что он использует раздел для каждого образа диска, но на самом деле он форматирует раздел с файловой системой по вашему выбору, монтирует его и сохраняет образы дисков в файловой системе. По функциональности он ничем не отличается от тома хранилища по умолчанию /var/lib/libvirt/images/
.
Пул хранения на основе LVM использует другой подход. Он создает логический том для каждого образа диска. Таким образом, существует сопоставление 1:1 между образом диска VM и томом LVM.
Если у вас есть пул хранения, вы можете использовать его при создании новых виртуальных машин. Что касается перемещения существующих образов, то это прямолинейно с подходом «на основе разделов»: скопируйте образы, а затем измените виртуальную машину, чтобы она указывала на скопированный образ. Для LVM... Честно говоря, я не уверен. Простой dd
для логического тома может сработать.
Вот рабочая версия с использованием вашего подхода:
#!/bin/bash
fileList="$1"
targetDir="$2"
## Read the list of files into an associative array
declare -A filesInFile
while IFS= read -r file; do
filesInFile["$file"]=1
done < "$fileList"
## Collect the files in the target dir
filesInDir=("$targetDir"/*);
for file in "${filesInDir[@]}"; do
file=${file##*/}; # get the name of the file; remove path
## If this file has no entry in the array, delete
if [[ -z "${filesInFile[$file]}" ]]; then
echo "rm $file"
fi
done
Удалите echo
, чтобы действительно удалить файлы. Обратите внимание, что я не проверяю, различается ли количество файлов, так как в этом не было особого смысла, учитывая, что количество файлов может быть одинаковым, но у вас все еще могут быть файлы, имя которых отсутствует в списке.
Сzsh
:
expected=(${(f)"$(<fileNames.txt)"}) || exit
cd TestDir || exit
actual=(*(D))
superfluous=(${actual:|expected})
if (($#superfluous)) {
echo These files are not in the expected list:
printf ' - %q\n' $superfluous
read -q '?Do you want to delete them? ' && rm -rf -- $superfluous
}
Вместо того, чтобы сохранять список файлов в переменной, зацикливайте имена:
for name in TestDir/*; do
# the rest of the code
done
Чтобы проверить, встречается ли $name
в fileNames.txt
, используйтеgrep -q
:
for name in TestDir/*; do
if ! grep -qxF "$name" fileNames.txt; then
echo rm "$name"
fi
done
-F
заставляет grep
выполнять сравнение строк, а не сопоставление с регулярным выражением. С -q
мы не получаем вывода из grep
, только статус выхода, который мы можем использовать с оператором if
(true, если строка была найдена, но восклицательный знак инвертирует смысл проверки ). -x
сообщает grep
, что строка $name
должна соответствовать всей строке от начала до конца, а не только части строки.
Я защитил настоящий rm
с помощью echo
. Запустите и убедитесь, что правильные файлы удаляются.
Если имена файлов указаны без пути TestDir
, измените $name
в команде grep
на${name##*/}
:
for name in TestDir/*; do
if ! grep -qxF "${name##*/}" fileNames.txt; then
echo rm "$name"
fi
done
Это будет искать часть имени файла пути в $name
, а не полный путь, включая TestDir
.