Как можно передать USB-накопитель на виртуальную машину, используя QEMU, без потери доступа к ОС хоста?

Вот вам кое-что. Во-первых, скрипт на Bash, поэтому не очень эффективен. Он не делает именно то, что вам нужно, поскольку проверяет только одну пару подсетей и сообщает о перекрытии. Ниже сценария следуют несколько грубых команд оболочки, хотя результат не представлен в той форме, которую вы хотите. Так что вам нужно интегрировать и настраивать всю связку под свои нужды или относиться к ним как к наброску, иллюстрирующему логику.

#!/usr/bin/env bash

subnet1="$1"
subnet2="$2"

# calculate min and max of subnet1
# calculate min and max of subnet2
# find the common range (check_overlap)
# print it if there is one

read_range () {
    IFS=/ read ip mask <<<"$1"
    IFS=. read -a octets <<< "$ip";
    set -- "${octets[@]}";
    min_ip=$(($1*256*256*256 + $2*256*256 + $3*256 + $4));
    host=$((32-mask))
    max_ip=$(($min_ip+(2**host)-1))
    printf "%d-%d\n" "$min_ip" "$max_ip"
}

check_overlap () {
    IFS=- read min1 max1 <<<"$1";
    IFS=- read min2 max2 <<<"$2";
    if [ "$max1" -lt "$min2" ] || [ "$max2" -lt "$min1" ]; then return; fi
    [ "$max1" -ge "$max2" ] && max="$max2" ||   max="$max1"
    [ "$min1" -le "$min2" ] && min="$min2" || min="$min1"
    printf "%s-%s\n" "$(to_octets $min)" "$(to_octets $max)"
}

to_octets () {
    first=$(($1>>24))
    second=$((($1&(256*256*255))>>16))
    third=$((($1&(256*255))>>8))
    fourth=$(($1&255))
    printf "%d.%d.%d.%d\n" "$first" "$second" "$third" "$fourth" 
}

range1="$(read_range $subnet1)"
range2="$(read_range $subnet2)"
overlap="$(check_overlap $range1 $range2)"
[ -n "$overlap" ] && echo "Overlap $overlap of $subnet1 and $subnet2"

Использование и результат таковы:

$./overlap.bash 194.33.26.0/26 194.33.24.0/22
Overlap 194.33.26.0-194.33.26.63 of 194.33.26.0/26 and 194.33.24.0/22

Теперь, когда ваш первый список подсетей находится в файле list, а подсети для проверки находятся в файле to_check, вы можете использовать сценарий для поиска всех совпадений.

$ while read l; do list+=("$l"); done < list
$ while read t; do to_check+=("$t"); done < to_check
$ for i in "${list[@]}"; do for j in "${to_check[@]}"; do \
./overlap.bash "$i" "$j"; done; done

Вот результат:

Overlap 194.33.26.0-194.33.26.63 of 194.33.24.0/22 and 194.33.26.0/26
Overlap 188.115.195.88-188.115.195.95 of 188.115.195.80/28 and 188.115.195.88/29
Overlap 41.202.219.32-41.202.219.63 of 41.202.219.32/27 and 41.202.219.0/24
Overlap 41.202.219.128-41.202.219.135 of 41.202.219.128/29 and 41.202.219.0/24
Overlap 41.202.219.208-41.202.219.223 of 41.202.219.208/28 and 41.202.219.0/24
Overlap 41.202.219.136-41.202.219.143 of 41.202.219.136/29 and 41.202.219.0/24
Overlap 197.157.209.128-197.157.209.143 of 197.157.209.0/24 and 197.157.209.128/28

Как видите, 41.202.219.0/24имеет четыре совпадения, вопреки вашим ожиданиям в вопросе.

Чтобы получить только те подсети, которые не пересекаются с первым списком, сценарий должен быть намного короче. Вам не нужна функция to_octets, а функция check_overlapуже может дать результат в этой строке:

if [ "$max1" -lt "$min2" ] || [ "$max2" -lt "$min1" ]; then return; fi

Также последние две строки могут быть изменены (при полном удалении последней ).

Что касается логики интегрирования, здесь есть место для короткой -схемы проверки по первому списку, так как не все комбинации должны проверяться. Достаточно одного минуса.

0
20.01.2020, 16:55
1 ответ

Нет, это невозможно. У вас не может быть доступа к устройству USB -с двух разных хостов USB -.

В вашем случае (внешний диск ), вы можете смонтировать его на хосте, а затем использовать 9p virtio для пересылки смонтированной папки гостю или использовать сетевые -технологии общего доступа к папкам, такие как nfs или smb.

http://www.linux-kvm.org/page/9p_virtio
https://de.wikipedia.org/wiki/Network_File_System

1
28.01.2020, 02:38

Теги

Похожие вопросы