312
312
-drive "${pflash_common},file=$nvram${nvram_ro:+,${nvram_ro}}" )
316
# inargs(needle, [ haystack [ more [ haystack [ ... ] ] ] ]
317
local needle="$1" i=""
320
[ "$i" = "$needle" ] && return 0
327
addr aio bps bps_max bus cache copy-on-read cyls file format \
328
group "if" index iops iops_max iops_size media serial snapshot \
333
# given a --drive= argument, if there is no 'file=' and
334
# one of the tokens is a file, improve that to have 'file=<that>'
335
local file="" i="" ret=""
337
*,file=*) _RET="$1"; return 0;;
339
IFS=","; set -- $1; IFS="$oifs"
341
if [ "${i#*=}" = "$i" -a -f "$i" -a -z "$file" ]; then
343
ret="file=$file${ret:+,${ret}}"
345
ret="${ret:+${ret},}$i"
352
local i="" ret="" oifs=""
353
IFS=","; set -- $1; IFS="$oifs"
355
is_drive_opt "$i" && ret="${ret:+$ret,}$i"
361
local i="" ret="" oifs=""
362
IFS=","; set -- $1; IFS="$oifs"
364
is_drive_opt "$i" || ret="${ret:+$ret,}$i"
371
IFS=","; set -- $2; IFS="$oifs"
373
[ "${i%%=*}" = "$name" ] && _RET=${i#*=} && return 0
380
out=$(LANG=C qemu-img info "$1") &&
381
fmt=$(echo "$out" | awk '$0 ~ /^file format:/ { print $3 }') &&
383
error "failed to determine format of $file";
391
# convert the '--disk' type argument into '-drive' and '-device'
392
local disks="" drives="" devices="" disk="" ret="" arg="" i=0
393
local drive_opts ffile="" driveid out="" fmt=""
394
declare -A drives # associative by id
399
while [ $i -lt "${#disks[@]}" ] && arg=${disks[$i]} && i=$(($i+1)); do
401
add_file_equal "$arg"
403
get_drive_opts "$arg"
405
echo "drive_opts=\"${_RET}\""
407
local other_drive_args="" other_id=""
408
local id="" file="" ffile="" fid=""
409
if extract_opt file "$drive_opts"; then
412
if [ -f "$file" ]; then
413
ffile=$(readlink -f "$file") ||
414
fail "failed readlink -f $file"
417
echo "file=$file ffile=$ffile"
419
extract_opt id "$drive_opts" && id="$_RET"
422
# Y N mention, use other
424
if [ -n "$ffile" ]; then
425
other_id=${file2id[$ffile]}
426
if [ -n "$other_id" ]; then
427
other_drive_opts=${drives[$other_id]}
432
if [ -n "$other_id" -a "${other_id}" != "$id" -a -n "$id" ]; then
433
error "file $file ($ffile) used by differing ids ($other_id, $id):"
434
error " $other_drive_opts"
439
if [ -n "$other_id" -a -z "$id" ]; then
440
debug 1 "no id in '$drive_opts', and '$file' used before" \
441
"with $other_drive_opts (id=$other_id). using that for id."
443
# would be good to compare drive opts and error if they
444
# were meaningfully different.
445
drive_opts="${other_drive_opts}"
448
#if ! extract_opt share-rw "$drive_opts"; then
449
# drive_opts="${drive_opts:+${drive_opts},}share-rw=on"
450
# drives[$id]=$drive_opts
456
if [ -z "$id" ]; then
457
id=$(printf "drive%02d" "$i")
458
drive_opts="id=$id${drive_opts:+,${drive_opts}}"
463
# support 'format' or 'fmt' (legacy)
464
if [ -n "$file" ] && extract_opt fmt "$drive_opts"; then
465
drive_opts=${drive_opts/${_RET}/format=${_RET#*=}/}
467
if [ -n "$file" ] && ! extract_opt format "$drive_opts"; then
468
get_format "$file" && fmt=${_RET} || {
469
error "failed to get format for $file."
472
drive_opts="${drive_opts},format=$fmt"
474
drive_opts="${drive_opts:+${drive_opts},}if=none"
477
get_device_opts "$arg"
478
dev_opts="drive=${id}${_RET:+,${_RET}},share-rw=on"
480
if ! extract_opt serial "$dev_opts"; then
482
dev_opts="${dev_opts},serial=sn-$id"
485
# $def_disk_driver is inherited from scope
486
if extract_opt "if" "$dev_opts"; then
488
if=virtio) dev_opts="${dev_opts/${_RET}/if=virtio-blk}";;
489
if=scsi) dev_opts="${dev_opts/${_RET}/if=scsi-hd}";;
490
if=pflash) dev_opts="${dev_opts/${_RET}/if=}";;
493
dev_opts="${dev_opts:+${dev_opts},}driver=$def_disk_driver"
496
# make sure there is a bus= or index=
497
local bus="" unit="" index=""
498
extract_opt bus "$dev_opts" && bus=$_RET
499
extract_opt unit "$dev_opts" && unit=$_RET
500
extract_opt index "$dev_opts" && unit=$_RET
501
if [ -n "$bus" -o "$unit" ] && [ -n "$index" ]; then
502
error "bus and index can't be specified together: $arg"
504
elif [ -z "$bus" -a -z "$unit" -a -z "$index" ]; then
505
dev_opts="${dev_opts:+${dev_opts},}index=$i"
506
elif [ -n "$bus" -a -z "$unit" ]; then
507
dev_opts="${dev_opts:+${dev_opts},}unit=$i"
511
debug 1 "new drive: $file id=$id ${drive_opts}"
512
if [ -n "$ffile" ]; then
515
drives[$id]="$drive_opts"
518
devices[${#devices[@]}]="$dev_opts"
523
for i in "${!drives[@]}"; do
524
_RET[${#_RET[@]}]="-drive"
525
_RET[${#_RET[@]}]="${drives[$i]}"
526
#_RET[${#_RET[@]}]="-blockdev"
528
#t=${t/id=/node-name=}
530
#t=${t/file=/filename=}
531
#_RET[${#_RET[@]}]="$t"
533
for i in "${devices[@]}"; do
534
_RET[${#_RET[@]}]="-device"
535
_RET[${#_RET[@]}]="$i"
316
540
local short_opts="hd:n:v"
317
541
local long_opts="bios:,help,dowait,disk:,dry-run,kvm:,no-dowait,netdev:,uefi,uefi-nvram:,verbose"
407
631
{ error "failed to get bios opts"; return 1; }
408
632
bios_opts=( "${_RET[@]}" )
410
local out="" fmt="" bus="" unit="" index="" serial="" driver="" devopts=""
411
local busorindex="" driveopts="" cur="" val="" file=""
412
for((i=0;i<${#diskdevs[@]};i++)); do
414
IFS=","; set -- $cur; IFS="$oifs"
416
id=$(printf "disk%02d" "$i")
424
[ "${tok#*=}" = "${tok}" -a -f "${tok}" -a -z "$file" ] && file="$tok"
427
driver=*) driver=$val;;
428
if=virtio) driver=virtio-blk;;
429
if=scsi) driver=scsi-hd;;
431
if=sd|if=mtd|floppy) fail "do not know what to do with $tok on $cur";;
434
fmt=*|format=*) fmt=$val;;
435
serial=*) serial=$val;;
438
index=*) index=$val;;
441
[ -z "$file" ] && fail "did not read a file from $cur"
442
if [ -f "$file" -a -z "$fmt" ]; then
443
out=$(LANG=C qemu-img info "$file") &&
444
fmt=$(echo "$out" | awk '$0 ~ /^file format:/ { print $3 }') ||
445
{ error "failed to determine format of $file"; return 1; }
449
if [ -z "$driver" ]; then
450
driver="$def_disk_driver"
452
if [ -z "$serial" ]; then
456
# make sure we add either bus= or index=
457
if [ -n "$bus" -o "$unit" ] && [ -n "$index" ]; then
458
fail "bus and index cant be specified together: $cur"
459
elif [ -z "$bus" -a -z "$unit" -a -z "$index" ]; then
461
elif [ -n "$bus" -a -z "$unit" ]; then
465
busorindex="${bus:+bus=$bus,unit=$unit}${index:+index=${index}}"
466
diskopts="file=${file},id=$id,if=none,format=$fmt,$busorindex"
467
devopts="$driver,drive=$id${serial:+,serial=${serial}}"
470
id=*|if=*|driver=*|$file|file=*) continue;;
471
fmt=*|format=*) continue;;
472
serial=*|bus=*|unit=*|index=*) continue;;
474
isdevopt "$driver" "$tok" && devopts="${devopts},$tok" ||
475
diskopts="${diskopts},${tok}"
478
diskargs=( "${diskargs[@]}" -drive "$diskopts" -device "$devopts" )
634
args_from_disks "${diskdevs[@]}"
635
diskargs=( "${_RET[@]}" )
481
637
local mnics_vflag=""
482
638
for((i=0;i<${VERBOSITY}-1;i++)); do mnics_vflag="${mnics_vflag}v"; done