[libvirt] [PATCH 00/34] Add device addressing and disk controller support

This series is a merge of two previous series I posted http://www.redhat.com/archives/libvir-list/2009-December/msg00232.html http://www.redhat.com/archives/libvir-list/2009-December/msg00392.html It accomplishes quite a lot of things, having major impact on the QEMU driver, hopefully all in a postive way :-) In particular it does * Add standard XML syntax for addressing of PCI devices, and disk drives * Add support for disk controllers as a managed device in XML * Add support for disk controller hotplug/unplug * Convert everything over to use QEMU's -device flag where available * Add PCI addressing when using -device * Introduce a way to give every device a unique 'alias' name in the XML format I can't promise it works perfectly, but i've done quite alot of positive testing with it now & believe all the back comptability stuff is working right.

Only print out '.' for each test case, full test output can be re-enabled with VIR_TEST_VERBOSE=1, or VIR_TEST_DEBUG=XXXX Sample output now looks like TEST: statstest ........................................ 40 ................................... 75 OK PASS: statstest TEST: qparamtest ................................ 32 OK PASS: qparamtest TEST: ............ 12 OK --- tests/capabilityschematest | 5 ++- tests/daemon-conf | 27 ++++++---- tests/domainschematest | 5 ++- tests/esxutilstest.c | 2 +- tests/eventtest.c | 78 ++++++++++++++--------------- tests/interfaceschematest | 5 ++- tests/networkschematest | 5 ++- tests/nodedevschematest | 5 ++- tests/schematestutils.sh | 20 ++++---- tests/statstest.c | 4 +- tests/storagepoolschematest | 5 ++- tests/storagevolschematest | 5 ++- tests/test-lib.sh | 64 +++++++++++++++++++++++ tests/test_conf.sh | 23 +++------ tests/testutils.c | 117 +++++++++++++++++++++++++++++++++---------- tests/testutils.h | 4 +- tests/testutilsqemu.c | 2 +- tests/virsh-all | 25 ++++++--- 18 files changed, 277 insertions(+), 124 deletions(-) diff --git a/tests/capabilityschematest b/tests/capabilityschematest index 3a1acc5..e32f85d 100755 --- a/tests/capabilityschematest +++ b/tests/capabilityschematest @@ -1,6 +1,9 @@ #!/bin/sh -. ./schematestutils.sh +test -z "$srcdir" && srcdir=$(pwd) + +. "$srcdir/test-lib.sh" +. "$abs_srcdir/schematestutils.sh" DIRS="capabilityschemadata xencapsdata" SCHEMA="capability.rng" diff --git a/tests/daemon-conf b/tests/daemon-conf index 722fe4e..1eb4be1 100755 --- a/tests/daemon-conf +++ b/tests/daemon-conf @@ -2,15 +2,14 @@ # Get coverage of libvirtd's config-parsing code. test -z "$srcdir" && srcdir=$(pwd) -test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/.. -test -z "$abs_top_builddir" && abs_top_builddir=$(pwd)/.. +LC_ALL=C +. "$srcdir/test-lib.sh" -if test "$VERBOSE" = yes; then - set -x +if test "$verbose" = yes; then $abs_top_builddir/daemon/libvirtd --version fi -. "$srcdir/test-lib.sh" +test_intro "$this_test" test -z "$CONFIG_HEADER" && CONFIG_HEADER="$abs_top_builddir/config.h" @@ -30,10 +29,12 @@ sed -n 's/^#\([^ #]\)/\1/p' "$conf" > tmp.conf # time and running libvirtd with the resulting config. Each libvirtd # invocation must fail. n=$(wc -l < tmp.conf) -i=1 +i=0 +fail=0 while :; do + i=$(expr $i + 1) + param_name=$(sed -n "$i"'s/ = .*//p' tmp.conf) - printf "testing with corrupted config: $param_name\n" 1>&2 rhs=$(sed -n "$i"'s/.* = \(.*\)/\1/p' tmp.conf) f=in$i.conf case $rhs in @@ -59,9 +60,8 @@ while :; do # Check that the diagnostic we want appears grep "$msg" err 1>/dev/null 2>&1 RET=$? + test_result $i "corrupted config $param_name" $RET test "$RET" = "0" || fail=1 - - i=$(expr $i + 1) done # Run with the unmodified config file. @@ -76,13 +76,18 @@ sed 's,^log_outputs.*,log_outputs="3:file:'"$(pwd)/log"'",' tmp.conf > k \ || fail=1 mv k tmp.conf || fail=1 -printf "running libvirtd with a valid config file ($sleep_secs seconds)\n" 1>&2 $abs_top_builddir/daemon/libvirtd --pid-file=pid-file --config=tmp.conf > log 2>&1 & pid=$! sleep $sleep_secs kill $pid +RET=0 # Expect an orderly shut-down and successful exit. -wait $pid || fail=1 +wait $pid || RET=1 + +test_result $i "valid config file (sleeping $sleep_secs seconds)" $RET +test $RET = 0 || fail=1 + +test_final $i $fail # "cat log" would print this for non-root: # Cannot set group when not running as root diff --git a/tests/domainschematest b/tests/domainschematest index 28ee69a..41a5f47 100755 --- a/tests/domainschematest +++ b/tests/domainschematest @@ -1,6 +1,9 @@ #!/bin/sh -. ./schematestutils.sh +test -z "$srcdir" && srcdir=$(pwd) + +. "$srcdir/test-lib.sh" +. "$abs_srcdir/schematestutils.sh" DIRS="domainschemadata qemuxml2argvdata sexpr2xmldata xmconfigdata xml2sexprdata" SCHEMA="domain.rng" diff --git a/tests/esxutilstest.c b/tests/esxutilstest.c index 058280d..f73df48 100644 --- a/tests/esxutilstest.c +++ b/tests/esxutilstest.c @@ -75,7 +75,7 @@ testDiskNameToIndex(const void *data ATTRIBUTE_UNUSED) k = virDiskNameToIndex(name); if (k != i) { - if (virtTestGetDebug() > 0) { + if (virTestGetDebug() > 0) { fprintf(stderr, "\nExpect [%d]\n", i); fprintf(stderr, "Actual [%d]\n", k); } diff --git a/tests/eventtest.c b/tests/eventtest.c index 90c60bb..067e365 100644 --- a/tests/eventtest.c +++ b/tests/eventtest.c @@ -139,7 +139,7 @@ static void *eventThreadLoop(void *data ATTRIBUTE_UNUSED) { static int -verifyFired(int handle, int timer) +verifyFired(const char *name, int handle, int timer) { int handleFired = 0; int timerFired = 0; @@ -147,25 +147,25 @@ verifyFired(int handle, int timer) for (i = 0 ; i < NUM_FDS ; i++) { if (handles[i].fired) { if (i != handle) { - fprintf(stderr, "FAIL Handle %d fired, but expected %d\n", i, handle); + virtTestResult(name, 1, "Handle %d fired, but expected %d\n", i, handle); return EXIT_FAILURE; } else { if (handles[i].error != EV_ERROR_NONE) { - fprintf(stderr, "FAIL Handle %d fired, but had error %d\n", i, - handles[i].error); + virtTestResult(name, 1, "Handle %d fired, but had error %d\n", i, + handles[i].error); return EXIT_FAILURE; } handleFired = 1; } } else { if (i == handle) { - fprintf(stderr, "FAIL Handle %d should have fired, but didn't\n", handle); + virtTestResult(name, 1, "Handle %d should have fired, but didn't\n", handle); return EXIT_FAILURE; } } } if (handleFired != 1 && handle != -1) { - fprintf(stderr, "FAIL Something wierd happened, expecting handle %d\n", handle); + virtTestResult(name, 1, "Something wierd happened, expecting handle %d\n", handle); return EXIT_FAILURE; } @@ -173,34 +173,33 @@ verifyFired(int handle, int timer) for (i = 0 ; i < NUM_TIME ; i++) { if (timers[i].fired) { if (i != timer) { - fprintf(stderr, "FAIL Timer %d fired, but expected %d\n", i, timer); + virtTestResult(name, 1, "Timer %d fired, but expected %d\n", i, timer); return EXIT_FAILURE; } else { if (timers[i].error != EV_ERROR_NONE) { - fprintf(stderr, "FAIL Timer %d fired, but had error %d\n", i, - timers[i].error); + virtTestResult(name, 1, "Timer %d fired, but had error %d\n", i, + timers[i].error); return EXIT_FAILURE; } timerFired = 1; } } else { if (i == timer) { - fprintf(stderr, "FAIL Timer %d should have fired, but didn't\n", timer); + virtTestResult(name, 1, "Timer %d should have fired, but didn't\n", timer); return EXIT_FAILURE; } } } if (timerFired != 1 && timer != -1) { - fprintf(stderr, "FAIL Something wierd happened, expecting timer %d\n", timer); + virtTestResult(name, 1, "Something wierd happened, expecting timer %d\n", timer); return EXIT_FAILURE; } return EXIT_SUCCESS; } static void -startJob(const char *msg, int *test) +startJob(void) { - fprintf(stderr, "%2d: %s ", (*test)++, msg); eventThreadRunOnce = 1; eventThreadJobDone = 0; pthread_cond_signal(&eventThreadRunCond); @@ -210,7 +209,7 @@ startJob(const char *msg, int *test) } static int -finishJob(int handle, int timer) +finishJob(const char *name, int handle, int timer) { struct timespec waitTime; int rc; @@ -220,14 +219,14 @@ finishJob(int handle, int timer) while (!eventThreadJobDone && rc == 0) rc = pthread_cond_timedwait(&eventThreadJobCond, &eventThreadMutex, &waitTime); if (rc != 0) { - fprintf(stderr, "FAIL Timed out waiting for pipe event\n"); + virtTestResult(name, 1, "Timed out waiting for pipe event\n"); return EXIT_FAILURE; } - if (verifyFired(handle, timer) != EXIT_SUCCESS) + if (verifyFired(name, handle, timer) != EXIT_SUCCESS) return EXIT_FAILURE; - fprintf(stderr, "OK\n"); + virtTestResult(name, 0, NULL); return EXIT_SUCCESS; } @@ -252,7 +251,6 @@ mymain(int argc, char **argv) int i; pthread_t eventThread; char one = '1'; - int test = 1; progname = argv[0]; @@ -302,10 +300,10 @@ mymain(int argc, char **argv) /* First time, is easy - just try triggering one of our * registered handles */ - startJob("Simple write", &test); + startJob(); if (safewrite(handles[1].pipeFD[1], &one, 1) != 1) return EXIT_FAILURE; - if (finishJob(1, -1) != EXIT_SUCCESS) + if (finishJob("Simple write", 1, -1) != EXIT_SUCCESS) return EXIT_FAILURE; resetAll(); @@ -313,10 +311,10 @@ mymain(int argc, char **argv) /* Now lets delete one before starting poll(), and * try triggering another handle */ virEventRemoveHandleImpl(handles[0].watch); - startJob("Deleted before poll", &test); + startJob(); if (safewrite(handles[1].pipeFD[1], &one, 1) != 1) return EXIT_FAILURE; - if (finishJob(1, -1) != EXIT_SUCCESS) + if (finishJob("Deleted before poll", 1, -1) != EXIT_SUCCESS) return EXIT_FAILURE; resetAll(); @@ -327,13 +325,13 @@ mymain(int argc, char **argv) /* NB: this case is subject to a bit of a race condition. * We yield & sleep, and pray that the other thread gets * scheduled before we run EventRemoveHandleImpl */ - startJob("Interrupted during poll", &test); + startJob(); pthread_mutex_unlock(&eventThreadMutex); sched_yield(); usleep(100 * 1000); pthread_mutex_lock(&eventThreadMutex); virEventRemoveHandleImpl(handles[1].watch); - if (finishJob(-1, -1) != EXIT_SUCCESS) + if (finishJob("Interrupted during poll", -1, -1) != EXIT_SUCCESS) return EXIT_FAILURE; resetAll(); @@ -345,22 +343,22 @@ mymain(int argc, char **argv) * before poll() exits for the first safewrite(). We don't * see a hard failure in other cases, so nothing to worry * about */ - startJob("Deleted during dispatch", &test); + startJob(); handles[2].delete = handles[3].watch; if (safewrite(handles[2].pipeFD[1], &one, 1) != 1 || safewrite(handles[3].pipeFD[1], &one, 1) != 1) return EXIT_FAILURE; - if (finishJob(2, -1) != EXIT_SUCCESS) + if (finishJob("Deleted during dispatch", 2, -1) != EXIT_SUCCESS) return EXIT_FAILURE; resetAll(); /* Extreme fun, lets delete ourselves during dispatch */ - startJob("Deleted during dispatch", &test); + startJob(); handles[2].delete = handles[2].watch; if (safewrite(handles[2].pipeFD[1], &one, 1) != 1) return EXIT_FAILURE; - if (finishJob(2, -1) != EXIT_SUCCESS) + if (finishJob("Deleted during dispatch", 2, -1) != EXIT_SUCCESS) return EXIT_FAILURE; resetAll(); @@ -369,8 +367,8 @@ mymain(int argc, char **argv) /* Run a timer on its own */ virEventUpdateTimeoutImpl(timers[1].timer, 100); - startJob("Firing a timer", &test); - if (finishJob(-1, 1) != EXIT_SUCCESS) + startJob(); + if (finishJob("Firing a timer", -1, 1) != EXIT_SUCCESS) return EXIT_FAILURE; virEventUpdateTimeoutImpl(timers[1].timer, -1); @@ -380,8 +378,8 @@ mymain(int argc, char **argv) * try triggering another timer */ virEventUpdateTimeoutImpl(timers[1].timer, 100); virEventRemoveTimeoutImpl(timers[0].timer); - startJob("Deleted before poll", &test); - if (finishJob(-1, 1) != EXIT_SUCCESS) + startJob(); + if (finishJob("Deleted before poll", -1, 1) != EXIT_SUCCESS) return EXIT_FAILURE; virEventUpdateTimeoutImpl(timers[1].timer, -1); @@ -393,13 +391,13 @@ mymain(int argc, char **argv) /* NB: this case is subject to a bit of a race condition. * We yield & sleep, and pray that the other thread gets * scheduled before we run EventRemoveTimeoutImpl */ - startJob("Interrupted during poll", &test); + startJob(); pthread_mutex_unlock(&eventThreadMutex); sched_yield(); usleep(100 * 1000); pthread_mutex_lock(&eventThreadMutex); virEventRemoveTimeoutImpl(timers[1].timer); - if (finishJob(-1, -1) != EXIT_SUCCESS) + if (finishJob("Interrupted during poll", -1, -1) != EXIT_SUCCESS) return EXIT_FAILURE; resetAll(); @@ -413,9 +411,9 @@ mymain(int argc, char **argv) * about */ virEventUpdateTimeoutImpl(timers[2].timer, 100); virEventUpdateTimeoutImpl(timers[3].timer, 100); - startJob("Deleted during dispatch", &test); + startJob(); timers[2].delete = timers[3].timer; - if (finishJob(-1, 2) != EXIT_SUCCESS) + if (finishJob("Deleted during dispatch", -1, 2) != EXIT_SUCCESS) return EXIT_FAILURE; virEventUpdateTimeoutImpl(timers[2].timer, -1); @@ -423,9 +421,9 @@ mymain(int argc, char **argv) /* Extreme fun, lets delete ourselves during dispatch */ virEventUpdateTimeoutImpl(timers[2].timer, 100); - startJob("Deleted during dispatch", &test); + startJob(); timers[2].delete = timers[2].timer; - if (finishJob(-1, 2) != EXIT_SUCCESS) + if (finishJob("Deleted during dispatch", -1, 2) != EXIT_SUCCESS) return EXIT_FAILURE; for (i = 0 ; i < NUM_FDS ; i++) @@ -448,10 +446,10 @@ mymain(int argc, char **argv) VIR_EVENT_HANDLE_READABLE, testPipeReader, &handles[1], NULL); - startJob("Write duplicate", &test); + startJob(); if (safewrite(handles[1].pipeFD[1], &one, 1) != 1) return EXIT_FAILURE; - if (finishJob(1, -1) != EXIT_SUCCESS) + if (finishJob("Write duplicate", 1, -1) != EXIT_SUCCESS) return EXIT_FAILURE; //pthread_kill(eventThread, SIGTERM); diff --git a/tests/interfaceschematest b/tests/interfaceschematest index e9ec2a4..66d8890 100755 --- a/tests/interfaceschematest +++ b/tests/interfaceschematest @@ -1,6 +1,9 @@ #!/bin/sh -. ./schematestutils.sh +test -z "$srcdir" && srcdir=$(pwd) + +. "$srcdir/test-lib.sh" +. "$abs_srcdir/schematestutils.sh" DIRS="interfaceschemadata" SCHEMA="interface.rng" diff --git a/tests/networkschematest b/tests/networkschematest index 01b2e6f..1bad45d 100755 --- a/tests/networkschematest +++ b/tests/networkschematest @@ -1,6 +1,9 @@ #!/bin/sh -. ./schematestutils.sh +test -z "$srcdir" && srcdir=$(pwd) + +. "$srcdir/test-lib.sh" +. "$abs_srcdir/schematestutils.sh" DIRS="../src/network networkxml2xmlin networkxml2xmlout" SCHEMA="network.rng" diff --git a/tests/nodedevschematest b/tests/nodedevschematest index 2f0e2b9..112fa6f 100755 --- a/tests/nodedevschematest +++ b/tests/nodedevschematest @@ -1,6 +1,9 @@ #!/bin/sh -. ./schematestutils.sh +test -z "$srcdir" && srcdir=$(pwd) + +. "$srcdir/test-lib.sh" +. "$abs_srcdir/schematestutils.sh" DIRS="nodedevschemadata" SCHEMA="nodedev.rng" diff --git a/tests/schematestutils.sh b/tests/schematestutils.sh index 56e6d83..1ad13fa 100644 --- a/tests/schematestutils.sh +++ b/tests/schematestutils.sh @@ -1,12 +1,11 @@ #!/bin/sh -test -z "$srcdir" && srcdir=`pwd` -test -z "$abs_srcdir" && abs_srcdir=`pwd` - check_schema () { DIRS=$1 -SCHEMA="$srcdir/../docs/schemas/$2" +SCHEMA="$abs_srcdir/../docs/schemas/$2" + +test_intro $NAME n=0 f=0 @@ -17,20 +16,21 @@ do for xml in $XML do n=`expr $n + 1` - printf "%4d) %.60s " $n $(basename $(dirname $xml))"/"$(basename $xml) cmd="xmllint --relaxng $SCHEMA --noout $xml" result=`$cmd 2>&1` ret=$? - if test $ret = 0; then - echo "OK" - else - echo "FAILED" + + test_result $n $(basename $(dirname $xml))"/"$(basename $xml) $ret + if test "$verbose" = "1" -a $ret != 0 ; then echo -e "$cmd\n$result" + fi + if test "$ret" != 0 ; then f=`expr $f + 1` fi done done -echo "Validated $n files, $f failed" + +test_final $n $f ret=0 test $f != 0 && ret=255 diff --git a/tests/statstest.c b/tests/statstest.c index 4c2ea7f..c7a5430 100644 --- a/tests/statstest.c +++ b/tests/statstest.c @@ -25,7 +25,7 @@ static int testDevice(const char *path, int expect) if (actual == expect) { return 0; } else { - if (virtTestGetDebug()) + if (virTestGetDebug()) fprintf(stderr, "Expect %-6d Actual %-6d\n", expect, actual); return -1; } @@ -55,7 +55,7 @@ mymain(int argc ATTRIBUTE_UNUSED, * register a handler to stop error messages cluttering * up display */ - if (!virtTestGetDebug()) + if (!virTestGetDebug()) virSetErrorFunc(NULL, testQuietError); #define DO_TEST(dev, num) \ diff --git a/tests/storagepoolschematest b/tests/storagepoolschematest index 57b2f7b..942c542 100755 --- a/tests/storagepoolschematest +++ b/tests/storagepoolschematest @@ -1,6 +1,9 @@ #!/bin/sh -. ./schematestutils.sh +test -z "$srcdir" && srcdir=$(pwd) + +. "$srcdir/test-lib.sh" +. "$abs_srcdir/schematestutils.sh" DIRS="storagepoolxml2xmlin storagepoolxml2xmlout" SCHEMA="storagepool.rng" diff --git a/tests/storagevolschematest b/tests/storagevolschematest index 32a8657..1f231c2 100755 --- a/tests/storagevolschematest +++ b/tests/storagevolschematest @@ -1,6 +1,9 @@ #!/bin/sh -. ./schematestutils.sh +test -z "$srcdir" && srcdir=$(pwd) + +. "$srcdir/test-lib.sh" +. "$abs_srcdir/schematestutils.sh" DIRS="storagevolxml2xmlin storagevolxml2xmlout" SCHEMA="storagevol.rng" diff --git a/tests/test-lib.sh b/tests/test-lib.sh index a007109..43265f3 100644 --- a/tests/test-lib.sh +++ b/tests/test-lib.sh @@ -1,5 +1,11 @@ # source this file; set up for tests +test -z "$abs_srcdir" && abs_srcdir=$(pwd) +test -z "$abs_builddir" && abs_builddir=$(pwd) +test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/.. +test -z "$abs_top_builddir" && abs_top_builddir=$(pwd)/.. +test -z "$LC_ALL" && LC_ALL=C + # Skip this test if the shell lacks support for functions. unset function_test eval 'function_test() { return 11; }; function_test' @@ -8,6 +14,59 @@ if test $? != 11; then (exit 77); exit 77 fi +test_intro() +{ + name=$1 + if test "$verbose" = "0" ; then + echo "TEST: $name" + echo -n " " + fi +} + +test_result() +{ + counter=$1 + name=$2 + status=$3 + if test "$verbose" = "0" ; then + mod=`eval "expr \( $counter - 1 \) % 40"` + if test "$counter" != 1 -a "$mod" = 0 ; then + printf " %-3d\n" `eval "expr $counter - 1"` + echo -n " " + fi + if test "$status" = "0" ; then + echo -n "." + else + echo -n "!" + fi + else + if test "$status" = "0" ; then + printf "%3d) %-60s ... OK\n" "$counter" "$name" + else + printf "%3d) %-60s ... FAILED\n" "$counter" "$name" + fi + fi +} + +test_final() +{ + counter=$1 + status=$2 + + if test "$verbose" = "0" ; then + mod=`eval "expr \( $counter + 1 \) % 40"` + for i in `seq $mod 40` + do + echo -n " " + done + if test "$status" = "0" ; then + printf " %-3d OK\n" $counter + else + printf " %-3d FAILED\n" $counter + fi + fi +} + skip_test_() { echo "$0: skipping test: $@" 1>&2 @@ -137,6 +196,11 @@ test_dir_=$(pwd) this_test_() { echo "./$0" | sed 's,.*/,,'; } this_test=$(this_test_) +verbose=0 +if test -n "$VIR_TEST_DEBUG" -o -n "$VIR_TEST_VERBOSE" ; then + verbose=1 +fi + # This is a stub function that is run upon trap (upon regular exit and # interrupt). Override it with a per-test function, e.g., to unmount # a partition, or to undo any other global state changes. diff --git a/tests/test_conf.sh b/tests/test_conf.sh index 682f1f5..aa7abf6 100755 --- a/tests/test_conf.sh +++ b/tests/test_conf.sh @@ -1,35 +1,28 @@ #!/bin/sh test -z "$srcdir" && srcdir=$(pwd) -test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/.. -test -z "$abs_top_builddir" && abs_top_builddir=$(pwd)/.. -test -z "$abs_srcdir" && abs_srcdir=$(pwd) -test -z "$abs_builddir" && abs_builddir=$(pwd) - -if test "$VERBOSE" = yes; then - set -x - $abs_top_builddir/tools/virsh --version -fi . "$srcdir/test-lib.sh" -set -e +test_intro $this_test fail=0 -i=1 +i=0 data_dir=$abs_srcdir/confdata for f in $(cd "$data_dir" && echo *.conf) do + i=`expr $i + 1` "$abs_builddir/conftest" "$data_dir/$f" > "$f-actual" expected="$data_dir"/`echo "$f" | sed s+\.conf$+\.out+` if compare "$expected" "$f-actual"; then - msg=OK + ret=0 else - msg=FAILED + ret=1 fail=1 fi - printf "%2d) %-60s ... %s\n" $i "$f" $msg - i=`expr $i + 1` + test_result $i "$f" $ret done +test_final $i $fail + (exit $fail); exit $fail diff --git a/tests/testutils.c b/tests/testutils.c index 25102ed..f31099e 100644 --- a/tests/testutils.c +++ b/tests/testutils.c @@ -46,6 +46,7 @@ ((int) ((T)->tv_usec - (U)->tv_usec))) / 1000.0) static unsigned int testDebug = -1; +static unsigned int testVerbose = -1; static unsigned int testOOM = 0; static unsigned int testCounter = 0; @@ -62,6 +63,38 @@ virtTestCountAverage(double *items, int nitems) return (double) (sum / nitems); } + +void virtTestResult(const char *name, int ret, const char *msg, ...) +{ + va_list vargs; + va_start(vargs, msg); + + testCounter++; + if (virTestGetVerbose()) { + fprintf(stderr, "%3d) %-60s ", testCounter, name); + if (ret == 0) + fprintf(stderr, "OK\n"); + else { + fprintf(stderr, "FAILED\n"); + if (msg) { + vfprintf(stderr, msg, vargs); + } + } + } else { + if (testCounter != 1 && + !((testCounter-1) % 40)) { + fprintf(stderr, " %-3d\n", (testCounter-1)); + fprintf(stderr, " "); + } + if (ret == 0) + fprintf(stderr, "."); + else + fprintf(stderr, "!"); + } + + va_end(vargs); +} + /* * Runs test and count average time (if the nloops is grater than 1) * @@ -76,8 +109,8 @@ virtTestRun(const char *title, int nloops, int (*body)(const void *data), const testCounter++; if (testOOM < 2) { - fprintf(stderr, "%2d) %-65s ... ", testCounter, title); - fflush(stderr); + if (virTestGetVerbose()) + fprintf(stderr, "%2d) %-65s ... ", testCounter, title); } if (nloops > 1 && (ts = calloc(nloops, @@ -97,13 +130,25 @@ virtTestRun(const char *title, int nloops, int (*body)(const void *data), const } } if (testOOM < 2) { - if (ret == 0 && ts) - fprintf(stderr, "OK [%.5f ms]\n", - virtTestCountAverage(ts, nloops)); - else if (ret == 0) - fprintf(stderr, "OK\n"); - else - fprintf(stderr, "FAILED\n"); + if (virTestGetVerbose()) { + if (ret == 0 && ts) + fprintf(stderr, "OK [%.5f ms]\n", + virtTestCountAverage(ts, nloops)); + else if (ret == 0) + fprintf(stderr, "OK\n"); + else + fprintf(stderr, "FAILED\n"); + } else { + if (testCounter != 1 && + !((testCounter-1) % 40)) { + fprintf(stderr, " %-3d\n", (testCounter-1)); + fprintf(stderr, " "); + } + if (ret == 0) + fprintf(stderr, "."); + else + fprintf(stderr, "!"); + } } free(ts); @@ -255,10 +300,10 @@ int virtTestDifference(FILE *stream, const char *actualStart = actual; const char *actualEnd = actual + (strlen(actual)-1); - if (!virtTestGetDebug()) + if (!virTestGetDebug()) return 0; - if (virtTestGetDebug() < 2) { + if (virTestGetDebug() < 2) { /* Skip to first character where they differ */ while (*expectStart && *actualStart && *actualStart == *expectStart) { @@ -322,26 +367,34 @@ virtTestErrorHook(int n, void *data ATTRIBUTE_UNUSED) } #endif -unsigned int -virtTestGetDebug() { - char *debugStr; - unsigned int debug; - - if (testDebug != -1) - return testDebug; +static unsigned int +virTestGetFlag(const char *name) { + char *flagStr; + unsigned int flag; - testDebug = 0; - - if ((debugStr = getenv("VIR_TEST_DEBUG")) == NULL) + if ((flagStr = getenv(name)) == NULL) return 0; - if (virStrToLong_ui(debugStr, NULL, 10, &debug) < 0) + if (virStrToLong_ui(flagStr, NULL, 10, &flag) < 0) return 0; - testDebug = debug; + return flag; +} + +unsigned int +virTestGetDebug() { + if (testDebug == -1) + testDebug = virTestGetFlag("VIR_TEST_DEBUG"); return testDebug; } +unsigned int +virTestGetVerbose() { + if (testVerbose == -1) + testVerbose = virTestGetFlag("VIR_TEST_VERBOSE"); + return testVerbose || virTestGetDebug(); +} + int virtTestMain(int argc, char **argv, int (*func)(int, char **)) @@ -357,6 +410,10 @@ int virtTestMain(int argc, int worker = 0; #endif + fprintf(stderr, "TEST: %s\n", STRPREFIX(argv[0], "./") ? argv[0] + 2 : argv[0]); + if (!virTestGetVerbose()) + fprintf(stderr, " "); + if (virThreadInitialize() < 0 || virErrorInitialize() < 0 || virRandomInitialize(time(NULL) ^ getpid())) @@ -389,7 +446,7 @@ int virtTestMain(int argc, goto cleanup; #if TEST_OOM_TRACE - if (virtTestGetDebug()) + if (virTestGetDebug()) virAllocTestHook(virtTestErrorHook, NULL); #endif @@ -407,7 +464,7 @@ int virtTestMain(int argc, approxAlloc = virAllocTestCount(); testCounter++; - if (virtTestGetDebug()) + if (virTestGetDebug()) fprintf(stderr, "%d) OOM...\n", testCounter); else fprintf(stderr, "%d) OOM of %d allocs ", testCounter, approxAlloc); @@ -429,7 +486,7 @@ int virtTestMain(int argc, if (mp && (n % mp) != (worker - 1)) continue; - if (!virtTestGetDebug()) { + if (!virTestGetDebug()) { if (mp) fprintf(stderr, "%d", worker); else @@ -458,7 +515,7 @@ int virtTestMain(int argc, } } - if (virtTestGetDebug()) + if (virTestGetDebug()) fprintf(stderr, " ... OOM of %d allocs", approxAlloc); if (ret == EXIT_SUCCESS) @@ -472,6 +529,12 @@ cleanup: #endif virResetLastError(); + if (!virTestGetVerbose()) { + int i; + for (i = (testCounter % 40) ; i < 40 ; i++) + fprintf(stderr, " "); + fprintf(stderr, " %-3d %s\n", testCounter, ret == 0 ? "OK" : "FAIL"); + } return ret; } diff --git a/tests/testutils.h b/tests/testutils.h index e5d5750..1f03746 100644 --- a/tests/testutils.h +++ b/tests/testutils.h @@ -18,6 +18,7 @@ double virtTestCountAverage(double *items, int nitems); +void virtTestResult(const char *name, int ret, const char *msg, ...); int virtTestRun(const char *title, int nloops, int (*body)(const void *data), @@ -36,7 +37,8 @@ int virtTestDifference(FILE *stream, const char *expect, const char *actual); -unsigned int virtTestGetDebug(void); +unsigned int virTestGetDebug(void); +unsigned int virTestGetVerbose(void); int virtTestMain(int argc, char **argv, diff --git a/tests/testutilsqemu.c b/tests/testutilsqemu.c index eeeb5ec..b07ab48 100644 --- a/tests/testutilsqemu.c +++ b/tests/testutilsqemu.c @@ -132,7 +132,7 @@ virCapsPtr testQemuCapsInit(void) { NULL) == NULL) goto cleanup; - if (virtTestGetDebug()) { + if (virTestGetDebug()) { char *caps_str; caps_str = virCapabilitiesFormatXML(caps); diff --git a/tests/virsh-all b/tests/virsh-all index 81b3e57..f1eb82c 100755 --- a/tests/virsh-all +++ b/tests/virsh-all @@ -17,13 +17,6 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. test -z "$srcdir" && srcdir=$(pwd) -test -z "$abs_top_srcdir" && abs_top_srcdir=$(pwd)/.. -test -z "$abs_top_builddir" && abs_top_builddir=$(pwd)/.. - -if test "$VERBOSE" = yes; then - set -x - $abs_top_builddir/tools/virsh --version -fi . "$srcdir/test-lib.sh" @@ -35,10 +28,24 @@ $abs_top_builddir/tools/virsh -c $test_url help > cmds || framework_failure cmds=$(sed -n 's/^ \([^ ][^ ]*\) .*/\1/p' cmds) || framework_failure test -n "$cmds" || framework_failure +test_intro "virsh-all" + +counter=0 for i in $cmds; do - echo testing $i... 1>&2 - # For now, just run the command and ignore output and exit status. + counter=`eval "expr $counter + 1"` + + # For now, just run the command and ignore output $abs_top_builddir/tools/virsh -c $test_url $i < /dev/null > /dev/null 2>&1 + # Temporarily ignoring exit status + #status=$? + status=0 + test_result $counter $i $status + + if test "$status" = "1" ; then + fail=1 + fi done +test_final $counter $fail + (exit $fail); exit $fail -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:22:57PM +0000, Daniel P. Berrange wrote:
Only print out '.' for each test case, full test output can be re-enabled with VIR_TEST_VERBOSE=1, or VIR_TEST_DEBUG=XXXX
Sample output now looks like
TEST: statstest ........................................ 40 ................................... 75 OK PASS: statstest TEST: qparamtest ................................ 32 OK PASS: qparamtest TEST: ............ 12 OK
Okay, way more compact, ACK Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

All guest devices now use a common device address structure summarized by: enum virDomainDeviceAddressType { VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI, }; struct _virDomainDevicePCIAddress { unsigned int domain; unsigned int bus; unsigned int slot; unsigned int function; }; struct _virDomainDeviceInfo { int type; union { virDomainDevicePCIAddress pci; } addr; }; This replaces the anonymous structs in Disk/Net/Hostdev data structures. Where available, the address is *always* printed in the XML file, instead of being hidden in the internal state file. <address type='pci' domain='0x0000' bus='0x1e' slot='0x07' function='0x0'/> The structure definition is based on Wolfgang Mauerer's disk controller patch series. * docs/schemas/domain.rng: Define the <address> syntax and associate it with disk/net/hostdev devices * src/conf/domain_conf.h, src/conf/domain_conf.c, src/libvirt_private.syms: APIs for parsing/formatting address information. Also remove the QEMU specific 'pci_addr' attributes * src/qemu/qemu_driver.c: Replace use of 'pci_addr' attrs with new standardized format. --- docs/schemas/domain.rng | 55 +++++-- src/conf/domain_conf.c | 420 +++++++++++++++++++++++++++++++++------------- src/conf/domain_conf.h | 84 +++++----- src/libvirt_private.syms | 6 + src/qemu/qemu_driver.c | 64 ++++--- 5 files changed, 428 insertions(+), 201 deletions(-) diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 566b117..7e00e7f 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -385,6 +385,9 @@ <optional> <ref name="encryption"/> </optional> + <optional> + <ref name="address"/> + </optional> </define> <!-- A disk description can be either of type file or block @@ -715,6 +718,9 @@ <empty/> </element> </optional> + <optional> + <ref name="address"/> + </optional> </interleave> </define> <!-- @@ -1134,10 +1140,15 @@ <choice> <ref name="usbproduct"/> <ref name="usbaddress"/> - <ref name="pciaddress"/> + <element name="address"> + <ref name="pciaddress"/> + </element> </choice> </element> </group> + <optional> + <ref name="address"/> + </optional> </element> </define> <define name="usbproduct"> @@ -1163,22 +1174,20 @@ </element> </define> <define name="pciaddress"> - <element name="address"> - <optional> - <attribute name="domain"> - <ref name="pciDomain"/> - </attribute> - </optional> - <attribute name="bus"> - <ref name="pciBus"/> - </attribute> - <attribute name="slot"> - <ref name="pciSlot"/> - </attribute> - <attribute name="function"> - <ref name="pciFunc"/> + <optional> + <attribute name="domain"> + <ref name="pciDomain"/> </attribute> - </element> + </optional> + <attribute name="bus"> + <ref name="pciBus"/> + </attribute> + <attribute name="slot"> + <ref name="pciSlot"/> + </attribute> + <attribute name="function"> + <ref name="pciFunc"/> + </attribute> </define> <!-- Devices attached to a domain. @@ -1286,6 +1295,20 @@ </interleave> </element> </define> + + <define name="address"> + <element name="address"> + <choice> + <group> + <attribute name="type"> + <value>pci</value> + </attribute> + <ref name="pciaddress"/> + </group> + </choice> + </element> + </define> + <!-- Type library diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 0b4fe8b..f199c08 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -88,6 +88,10 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST, "hostdev", "watchdog") +VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST, + "none", + "pci") + VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST, "block", "file", @@ -357,6 +361,7 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def) VIR_FREE(def->driverName); VIR_FREE(def->driverType); virStorageEncryptionFree(def->encryption); + virDomainDeviceInfoClear(&def->info); VIR_FREE(def); } @@ -408,8 +413,10 @@ void virDomainNetDefFree(virDomainNetDefPtr def) } VIR_FREE(def->ifname); - VIR_FREE(def->nic_name); VIR_FREE(def->hostnet_name); + + virDomainDeviceInfoClear(&def->info); + VIR_FREE(def); } @@ -483,6 +490,7 @@ void virDomainHostdevDefFree(virDomainHostdevDefPtr def) return; VIR_FREE(def->target); + virDomainDeviceInfoClear(&def->info); VIR_FREE(def); } @@ -731,6 +739,220 @@ void virDomainRemoveInactive(virDomainObjListPtr doms, } +int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, + int type) +{ + if (info->type != type) + return 0; + + switch (info->type) { + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI: + return virDomainDevicePCIAddressIsValid(&info->addr.pci); + } + + return 0; +} + + +int virDomainDevicePCIAddressIsValid(virDomainDevicePCIAddressPtr addr) +{ + return addr->domain || addr->bus || addr->slot; +} + + +int virDomainDeviceInfoIsSet(virDomainDeviceInfoPtr info) +{ + if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + return 1; + return 0; +} + + +void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info) +{ + memset(&info->addr, 0, sizeof(info->addr)); + info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE; +} + + +/* Generate a string representation of a device address + * @param address Device address to stringify + */ +static int virDomainDeviceInfoFormat(virBufferPtr buf, + virDomainDeviceInfoPtr info) +{ + if (!info) { + virDomainReportError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", + _("missing device information")); + return -1; + } + + if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + return 0; + + /* We'll be in domain/devices/[device type]/ so 3 level indent */ + virBufferVSprintf(buf, " <address type='%s'", + virDomainDeviceAddressTypeToString(info->type)); + + switch (info->type) { + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI: + virBufferVSprintf(buf, " domain='0x%.4x' bus='0x%.2x' slot='0x%.2x' function='0x%.1x'", + info->addr.pci.domain, + info->addr.pci.bus, + info->addr.pci.slot, + info->addr.pci.function); + break; + + default: + virDomainReportError(NULL, VIR_ERR_INTERNAL_ERROR, + _("unknown address type '%d'"), info->type); + return -1; + } + + virBufferAddLit(buf, "/>\n"); + + return 0; +} + + +int virDomainDevicePCIAddressEqual(virDomainDevicePCIAddressPtr a, + virDomainDevicePCIAddressPtr b) +{ + if (a->domain == b->domain && + a->bus == b->bus && + a->slot == b->slot && + a->function == b->function) + return 1; + + return 0; +} + + +static int +virDomainDevicePCIAddressParseXML(virConnectPtr conn, + xmlNodePtr node, + virDomainDevicePCIAddressPtr addr) +{ + char *domain, *slot, *bus, *function; + int ret = -1; + + memset(addr, 0, sizeof(*addr)); + + domain = virXMLPropString(node, "domain"); + bus = virXMLPropString(node, "bus"); + slot = virXMLPropString(node, "slot"); + function = virXMLPropString(node, "function"); + + if (domain && + virStrToLong_ui(domain, NULL, 16, &addr->domain) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse <address> 'domain' attribute")); + goto cleanup; + } + + if (bus && + virStrToLong_ui(bus, NULL, 16, &addr->bus) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse <address> 'bus' attribute")); + goto cleanup; + } + + if (slot && + virStrToLong_ui(slot, NULL, 16, &addr->slot) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse <address> 'slot' attribute")); + goto cleanup; + } + + if (function && + virStrToLong_ui(function, NULL, 16, &addr->function) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse <address> 'function' attribute")); + goto cleanup; + } + + if (!virDomainDevicePCIAddressIsValid(addr)) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Insufficient specification for PCI address")); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FREE(domain); + VIR_FREE(bus); + VIR_FREE(slot); + VIR_FREE(function); + return ret; +} + + +/* Parse the XML definition for a device address + * @param node XML nodeset to parse for device address definition + */ +static int +virDomainDeviceInfoParseXML(virConnectPtr conn, + xmlNodePtr node, + virDomainDeviceInfoPtr info, + unsigned int flags ATTRIBUTE_UNUSED) +{ + xmlNodePtr cur; + xmlNodePtr address = NULL; + char *type = NULL; + int ret = -1; + + virDomainDeviceInfoClear(info); + + cur = node->children; + while (cur != NULL) { + if (cur->type == XML_ELEMENT_NODE) { + if (address == NULL && + xmlStrEqual(cur->name, BAD_CAST "address")) { + address = cur; + } + } + cur = cur->next; + } + + if (!address) + return 0; + + type = virXMLPropString(address, "type"); + + if (type) { + if ((info->type = virDomainDeviceAddressTypeFromString(type)) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("unknown address type '%s'"), type); + goto cleanup; + } + } else { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("No type specified for device address")); + goto cleanup; + } + + switch (info->type) { + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI: + if (virDomainDevicePCIAddressParseXML(conn, address, &info->addr.pci) < 0) + goto cleanup; + break; + + default: + /* Should not happen */ + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("Unknown device address type")); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FREE(type); + return ret; +} + + /* Parse the XML definition for a disk * @param node XML nodeset to parse for disk definition */ @@ -819,6 +1041,7 @@ virDomainDiskDefParseXML(virConnectPtr conn, def->shared = 1; } else if ((flags & VIR_DOMAIN_XML_INTERNAL_STATUS) && xmlStrEqual(cur->name, BAD_CAST "state")) { + /* Legacy back-compat. Don't add any more attributes here */ devaddr = virXMLPropString(cur, "devaddr"); } else if (encryption == NULL && xmlStrEqual(cur->name, BAD_CAST "encryption")) { @@ -928,15 +1151,20 @@ virDomainDiskDefParseXML(virConnectPtr conn, goto error; } - if (devaddr && - sscanf(devaddr, "%x:%x:%x", - &def->pci_addr.domain, - &def->pci_addr.bus, - &def->pci_addr.slot) < 3) { - virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, - _("Unable to parse devaddr parameter '%s'"), - devaddr); - goto error; + if (devaddr) { + if (sscanf(devaddr, "%x:%x:%x", + &def->info.addr.pci.domain, + &def->info.addr.pci.bus, + &def->info.addr.pci.slot) < 3) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("Unable to parse devaddr parameter '%s'"), + devaddr); + goto error; + } + def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + } else { + if (virDomainDeviceInfoParseXML(conn, node, &def->info, flags) < 0) + goto error; } def->src = source; @@ -1153,6 +1381,7 @@ virDomainNetDefParseXML(virConnectPtr conn, model = virXMLPropString(cur, "type"); } else if ((flags & VIR_DOMAIN_XML_INTERNAL_STATUS) && xmlStrEqual(cur->name, BAD_CAST "state")) { + /* Legacy back-compat. Don't add any more attributes here */ nic_name = virXMLPropString(cur, "nic"); hostnet_name = virXMLPropString(cur, "hostnet"); devaddr = virXMLPropString(cur, "devaddr"); @@ -1173,14 +1402,28 @@ virDomainNetDefParseXML(virConnectPtr conn, virCapabilitiesGenerateMac(caps, def->mac); } - if (devaddr && - sscanf(devaddr, "%x:%x:%x", - &def->pci_addr.domain, - &def->pci_addr.bus, - &def->pci_addr.slot) < 3) { - virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, - _("Unable to parse devaddr parameter '%s'"), - devaddr); + if (devaddr) { + if (sscanf(devaddr, "%x:%x:%x", + &def->info.addr.pci.domain, + &def->info.addr.pci.bus, + &def->info.addr.pci.slot) < 3) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("Unable to parse devaddr parameter '%s'"), + devaddr); + goto error; + } + def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + } else { + if (virDomainDeviceInfoParseXML(conn, node, &def->info, flags) < 0) + goto error; + } + + /* XXX what about ISA/USB based NIC models - once we support + * them we should make sure address type is correct */ + if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Network interfaces must use 'pci' address type")); goto error; } @@ -2321,83 +2564,27 @@ virDomainHostdevSubsysPciDefParseXML(virConnectPtr conn, while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE) { if (xmlStrEqual(cur->name, BAD_CAST "address")) { + virDomainDevicePCIAddressPtr addr = + &def->source.subsys.u.pci; - char *domain = virXMLPropString(cur, "domain"); - if (domain) { - if (virStrToLong_ui(domain, NULL, 0, - &def->source.subsys.u.pci.domain) < 0) { - virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, - _("cannot parse domain %s"), - domain); - VIR_FREE(domain); - goto out; - } - VIR_FREE(domain); - } - - char *bus = virXMLPropString(cur, "bus"); - if (bus) { - if (virStrToLong_ui(bus, NULL, 0, - &def->source.subsys.u.pci.bus) < 0) { - virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, - _("cannot parse bus %s"), bus); - VIR_FREE(bus); - goto out; - } - VIR_FREE(bus); - } else { - virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, - "%s", _("pci address needs bus id")); - goto out; - } - - char *slot = virXMLPropString(cur, "slot"); - if (slot) { - if (virStrToLong_ui(slot, NULL, 0, - &def->source.subsys.u.pci.slot) < 0) { - virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, - _("cannot parse slot %s"), - slot); - VIR_FREE(slot); - goto out; - } - VIR_FREE(slot); - } else { - virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, - "%s", _("pci address needs slot id")); - goto out; - } - - char *function = virXMLPropString(cur, "function"); - if (function) { - if (virStrToLong_ui(function, NULL, 0, - &def->source.subsys.u.pci.function) < 0) { - virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, - _("cannot parse function %s"), - function); - VIR_FREE(function); - goto out; - } - VIR_FREE(function); - } else { - virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", - _("pci address needs function id")); + if (virDomainDevicePCIAddressParseXML(conn, cur, addr) < 0) goto out; - } } else if ((flags & VIR_DOMAIN_XML_INTERNAL_STATUS) && xmlStrEqual(cur->name, BAD_CAST "state")) { + /* Legacy back-compat. Don't add any more attributes here */ char *devaddr = virXMLPropString(cur, "devaddr"); if (devaddr && sscanf(devaddr, "%x:%x:%x", - &def->source.subsys.u.pci.guest_addr.domain, - &def->source.subsys.u.pci.guest_addr.bus, - &def->source.subsys.u.pci.guest_addr.slot) < 3) { + &def->info.addr.pci.domain, + &def->info.addr.pci.bus, + &def->info.addr.pci.slot) < 3) { virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, _("Unable to parse devaddr parameter '%s'"), devaddr); VIR_FREE(devaddr); goto out; } + def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; } else { virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, _("unknown pci source type '%s'"), @@ -2475,14 +2662,29 @@ virDomainHostdevDefParseXML(virConnectPtr conn, if (virDomainHostdevSubsysPciDefParseXML(conn, cur, def, flags) < 0) goto error; } - } else { - virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, - _("unknown node %s"), cur->name); } } cur = cur->next; } + if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { + if (virDomainDeviceInfoParseXML(conn, node, &def->info, flags) < 0) + goto error; + } + + if (def->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { + switch (def->source.subsys.type) { + case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: + if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("PCI host devices must use 'pci' address type")); + goto error; + } + break; + } + } + cleanup: VIR_FREE(type); VIR_FREE(mode); @@ -3869,8 +4071,7 @@ virDomainLifecycleDefFormat(virConnectPtr conn, static int virDomainDiskDefFormat(virConnectPtr conn, virBufferPtr buf, - virDomainDiskDefPtr def, - int flags) + virDomainDiskDefPtr def) { const char *type = virDomainDiskTypeToString(def->type); const char *device = virDomainDiskDeviceTypeToString(def->device); @@ -3947,15 +4148,8 @@ virDomainDiskDefFormat(virConnectPtr conn, virStorageEncryptionFormat(conn, buf, def->encryption) < 0) return -1; - if (flags & VIR_DOMAIN_XML_INTERNAL_STATUS) { - virBufferAddLit(buf, " <state"); - if (virDiskHasValidPciAddr(def)) - virBufferVSprintf(buf, " devaddr='%.4x:%.2x:%.2x'", - def->pci_addr.domain, - def->pci_addr.bus, - def->pci_addr.slot); - virBufferAddLit(buf, "/>\n"); - } + if (virDomainDeviceInfoFormat(buf, &def->info) < 0) + return -1; virBufferAddLit(buf, " </disk>\n"); @@ -4089,21 +4283,18 @@ virDomainNetDefFormat(virConnectPtr conn, def->model); if (flags & VIR_DOMAIN_XML_INTERNAL_STATUS) { + /* Legacy back-compat. Don't add any more attributes here */ virBufferAddLit(buf, " <state"); - if (def->nic_name) - virBufferEscapeString(buf, " nic='%s'", def->nic_name); if (def->hostnet_name) virBufferEscapeString(buf, " hostnet='%s'", def->hostnet_name); - if (virNetHasValidPciAddr(def)) - virBufferVSprintf(buf, " devaddr='%.4x:%.2x:%.2x'", - def->pci_addr.domain, - def->pci_addr.bus, - def->pci_addr.slot); if (def->vlan > 0) virBufferVSprintf(buf, " vlan='%d'", def->vlan); virBufferAddLit(buf, "/>\n"); } + if (virDomainDeviceInfoFormat(buf, &def->info) < 0) + return -1; + virBufferAddLit(buf, " </interface>\n"); return 0; @@ -4477,8 +4668,7 @@ virDomainGraphicsDefFormat(virConnectPtr conn, static int virDomainHostdevDefFormat(virConnectPtr conn, virBufferPtr buf, - virDomainHostdevDefPtr def, - int flags) + virDomainHostdevDefPtr def) { const char *mode = virDomainHostdevModeTypeToString(def->mode); const char *type; @@ -4512,25 +4702,19 @@ virDomainHostdevDefFormat(virConnectPtr conn, def->source.subsys.u.usb.bus, def->source.subsys.u.usb.device); } - } - if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { + } else if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { virBufferVSprintf(buf, " <address domain='0x%.4x' bus='0x%.2x' slot='0x%.2x' function='0x%.1x'/>\n", def->source.subsys.u.pci.domain, def->source.subsys.u.pci.bus, def->source.subsys.u.pci.slot, def->source.subsys.u.pci.function); - if (flags & VIR_DOMAIN_XML_INTERNAL_STATUS) { - virBufferAddLit(buf, " <state"); - if (virHostdevHasValidGuestAddr(def)) - virBufferVSprintf(buf, " devaddr='%.4x:%.2x:%.2x'", - def->source.subsys.u.pci.guest_addr.domain, - def->source.subsys.u.pci.guest_addr.bus, - def->source.subsys.u.pci.guest_addr.slot); - virBufferAddLit(buf, "/>\n"); - } } virBufferAddLit(buf, " </source>\n"); + + if (virDomainDeviceInfoFormat(buf, &def->info) < 0) + return -1; + virBufferAddLit(buf, " </hostdev>\n"); return 0; @@ -4695,7 +4879,7 @@ char *virDomainDefFormat(virConnectPtr conn, def->emulator); for (n = 0 ; n < def->ndisks ; n++) - if (virDomainDiskDefFormat(conn, &buf, def->disks[n], flags) < 0) + if (virDomainDiskDefFormat(conn, &buf, def->disks[n]) < 0) goto cleanup; for (n = 0 ; n < def->nfss ; n++) @@ -4763,7 +4947,7 @@ char *virDomainDefFormat(virConnectPtr conn, goto cleanup; for (n = 0 ; n < def->nhostdevs ; n++) - if (virDomainHostdevDefFormat(conn, &buf, def->hostdevs[n], flags) < 0) + if (virDomainHostdevDefFormat(conn, &buf, def->hostdevs[n]) < 0) goto cleanup; if (def->watchdog) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a807e9d..c50aae0 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -64,6 +64,32 @@ enum virDomainVirtType { VIR_DOMAIN_VIRT_LAST, }; +enum virDomainDeviceAddressType { + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE, + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI, + + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST +}; + +typedef struct _virDomainDevicePCIAddress virDomainDevicePCIAddress; +typedef virDomainDevicePCIAddress *virDomainDevicePCIAddressPtr; +struct _virDomainDevicePCIAddress { + unsigned int domain; + unsigned int bus; + unsigned int slot; + unsigned int function; +}; + +typedef struct _virDomainDeviceInfo virDomainDeviceInfo; +typedef virDomainDeviceInfo *virDomainDeviceInfoPtr; +struct _virDomainDeviceInfo { + int type; + union { + virDomainDevicePCIAddress pci; + } addr; +}; + + /* Two types of disk backends */ enum virDomainDiskType { VIR_DOMAIN_DISK_TYPE_BLOCK, @@ -119,20 +145,10 @@ struct _virDomainDiskDef { int cachemode; unsigned int readonly : 1; unsigned int shared : 1; - struct { - unsigned domain; - unsigned bus; - unsigned slot; - } pci_addr; + virDomainDeviceInfo info; virStorageEncryptionPtr encryption; }; -static inline int -virDiskHasValidPciAddr(virDomainDiskDefPtr def) -{ - return def->pci_addr.domain || def->pci_addr.bus || def->pci_addr.slot; -} - /* Two types of disk backends */ enum virDomainFSType { @@ -199,22 +215,15 @@ struct _virDomainNetDef { } internal; } data; char *ifname; + virDomainDeviceInfo info; + /* XXX figure out how to remove this */ char *nic_name; + /* XXX figure out how to remove this */ char *hostnet_name; - struct { - unsigned domain; - unsigned bus; - unsigned slot; - } pci_addr; + /* XXX figure out how to remove this */ int vlan; }; -static inline int -virNetHasValidPciAddr(virDomainNetDefPtr def) -{ - return def->pci_addr.domain || def->pci_addr.bus || def->pci_addr.slot; -} - enum virDomainChrTargetType { VIR_DOMAIN_CHR_TARGET_TYPE_NULL = 0, VIR_DOMAIN_CHR_TARGET_TYPE_MONITOR, @@ -442,17 +451,7 @@ struct _virDomainHostdevDef { unsigned vendor; unsigned product; } usb; - struct { - unsigned domain; - unsigned bus; - unsigned slot; - unsigned function; - struct { - unsigned domain; - unsigned bus; - unsigned slot; - } guest_addr; - } pci; + virDomainDevicePCIAddress pci; /* host address */ } u; } subsys; struct { @@ -463,16 +462,9 @@ struct _virDomainHostdevDef { } caps; } source; char* target; + virDomainDeviceInfo info; /* Guest address */ }; -static inline int -virHostdevHasValidGuestAddr(virDomainHostdevDefPtr def) -{ - return def->source.subsys.u.pci.guest_addr.domain || - def->source.subsys.u.pci.guest_addr.bus || - def->source.subsys.u.pci.guest_addr.slot; -} - /* Flags for the 'type' field in next struct */ enum virDomainDeviceType { VIR_DOMAIN_DEVICE_DISK, @@ -673,6 +665,7 @@ virDomainObjIsActive(virDomainObjPtr dom) return dom->def->id != -1; } + int virDomainObjListInit(virDomainObjListPtr objs); void virDomainObjListDeinit(virDomainObjListPtr objs); @@ -695,6 +688,13 @@ void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def); void virDomainVideoDefFree(virDomainVideoDefPtr def); void virDomainHostdevDefFree(virDomainHostdevDefPtr def); void virDomainDeviceDefFree(virDomainDeviceDefPtr def); +int virDomainDevicePCIAddressEqual(virDomainDevicePCIAddressPtr a, + virDomainDevicePCIAddressPtr b); +int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, + int type); +int virDomainDevicePCIAddressIsValid(virDomainDevicePCIAddressPtr addr); +int virDomainDeviceInfoIsSet(virDomainDeviceInfoPtr info); +void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info); void virDomainDefFree(virDomainDefPtr vm); void virDomainObjRef(virDomainObjPtr vm); /* Returns 1 if the object was freed, 0 if more refs exist */ @@ -832,6 +832,8 @@ VIR_ENUM_DECL(virDomainBoot) VIR_ENUM_DECL(virDomainFeature) VIR_ENUM_DECL(virDomainLifecycle) VIR_ENUM_DECL(virDomainDevice) +VIR_ENUM_DECL(virDomainDeviceAddress) +VIR_ENUM_DECL(virDomainDeviceAddressMode) VIR_ENUM_DECL(virDomainDisk) VIR_ENUM_DECL(virDomainDiskDevice) VIR_ENUM_DECL(virDomainDiskBus) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 10940eb..67ffe69 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -174,6 +174,12 @@ virDomainObjListInit; virDomainObjListDeinit; virDomainObjRef; virDomainObjUnref; +virDomainDeviceAddressEqual; +virDomainDevicePCIAddressEqual; +virDomainDeviceAddressIsValid; +virDomainDevicePCIAddressIsValid; +virDomainDeviceInfoIsSet; +virDomainDeviceAddressClear; # domain_event.h diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index daa6f94..3588531 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -5098,13 +5098,15 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn, ret = qemuMonitorAddPCIDisk(priv->mon, dev->data.disk->src, type, - &dev->data.disk->pci_addr.domain, - &dev->data.disk->pci_addr.bus, - &dev->data.disk->pci_addr.slot); + &dev->data.disk->info.addr.pci.domain, + &dev->data.disk->info.addr.pci.bus, + &dev->data.disk->info.addr.pci.slot); qemuDomainObjExitMonitorWithDriver(driver, vm); - if (ret == 0) + if (ret == 0) { + dev->data.disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; virDomainDiskInsertPreAlloced(vm->def, dev->data.disk); + } return ret; } @@ -5227,12 +5229,13 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn, qemuDomainObjEnterMonitorWithDriver(driver, vm); if (qemuMonitorAddPCINetwork(priv->mon, nicstr, - &net->pci_addr.domain, - &net->pci_addr.bus, - &net->pci_addr.slot) < 0) { + &net->info.addr.pci.domain, + &net->info.addr.pci.bus, + &net->info.addr.pci.slot) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); goto try_remove; } + net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; qemuDomainObjExitMonitorWithDriver(driver, vm); ret = 0; @@ -5315,12 +5318,13 @@ static int qemudDomainAttachHostPciDevice(virConnectPtr conn, hostdev->source.subsys.u.pci.bus, hostdev->source.subsys.u.pci.slot, hostdev->source.subsys.u.pci.function, - &hostdev->source.subsys.u.pci.guest_addr.domain, - &hostdev->source.subsys.u.pci.guest_addr.bus, - &hostdev->source.subsys.u.pci.guest_addr.slot); + &hostdev->info.addr.pci.domain, + &hostdev->info.addr.pci.bus, + &hostdev->info.addr.pci.slot); qemuDomainObjExitMonitorWithDriver(driver, vm); if (ret < 0) goto error; + hostdev->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; vm->def->hostdevs[vm->def->nhostdevs++] = hostdev; @@ -5550,18 +5554,18 @@ static int qemudDomainDetachPciDiskDevice(virConnectPtr conn, goto cleanup; } - if (!virDiskHasValidPciAddr(detach)) { - qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, - _("disk %s cannot be detached - no PCI address for device"), - detach->dst); + if (!virDomainDeviceAddressIsValid(&detach->info, + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) { + qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, "%s", + _("device cannot be detached without a PCI address")); goto cleanup; } qemuDomainObjEnterMonitorWithDriver(driver, vm); if (qemuMonitorRemovePCIDevice(priv->mon, - detach->pci_addr.domain, - detach->pci_addr.bus, - detach->pci_addr.slot) < 0) { + detach->info.addr.pci.domain, + detach->info.addr.pci.bus, + detach->info.addr.pci.slot) < 0) { qemuDomainObjExitMonitor(vm); goto cleanup; } @@ -5616,7 +5620,14 @@ qemudDomainDetachNetDevice(virConnectPtr conn, goto cleanup; } - if (!virNetHasValidPciAddr(detach) || detach->vlan < 0 || !detach->hostnet_name) { + if (!virDomainDeviceAddressIsValid(&detach->info, + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) { + qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, + "%s", _("device cannot be detached without a PCI address")); + goto cleanup; + } + + if (detach->vlan < 0 || !detach->hostnet_name) { qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, "%s", _("network device cannot be detached - device state missing")); goto cleanup; @@ -5624,9 +5635,9 @@ qemudDomainDetachNetDevice(virConnectPtr conn, qemuDomainObjEnterMonitorWithDriver(driver, vm); if (qemuMonitorRemovePCIDevice(priv->mon, - detach->pci_addr.domain, - detach->pci_addr.bus, - detach->pci_addr.slot) < 0) { + detach->info.addr.pci.domain, + detach->info.addr.pci.bus, + detach->info.addr.pci.slot) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); goto cleanup; } @@ -5704,17 +5715,18 @@ static int qemudDomainDetachHostPciDevice(virConnectPtr conn, return -1; } - if (!virHostdevHasValidGuestAddr(detach)) { + if (!virDomainDeviceAddressIsValid(&detach->info, + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) { qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, - "%s", _("hostdev cannot be detached - device state missing")); + "%s", _("device cannot be detached without a PCI address")); return -1; } qemuDomainObjEnterMonitorWithDriver(driver, vm); if (qemuMonitorRemovePCIDevice(priv->mon, - detach->source.subsys.u.pci.guest_addr.domain, - detach->source.subsys.u.pci.guest_addr.bus, - detach->source.subsys.u.pci.guest_addr.slot) < 0) { + detach->info.addr.pci.domain, + detach->info.addr.pci.bus, + detach->info.addr.pci.slot) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); return -1; } -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:22:58PM +0000, Daniel P. Berrange wrote:
All guest devices now use a common device address structure summarized by:
enum virDomainDeviceAddressType { VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI, };
struct _virDomainDevicePCIAddress { unsigned int domain; unsigned int bus; unsigned int slot; unsigned int function; };
struct _virDomainDeviceInfo { int type; union { virDomainDevicePCIAddress pci; } addr; };
This replaces the anonymous structs in Disk/Net/Hostdev data structures. Where available, the address is *always* printed in the XML file, instead of being hidden in the internal state file.
<address type='pci' domain='0x0000' bus='0x1e' slot='0x07' function='0x0'/>
The structure definition is based on Wolfgang Mauerer's disk controller patch series.
* docs/schemas/domain.rng: Define the <address> syntax and associate it with disk/net/hostdev devices * src/conf/domain_conf.h, src/conf/domain_conf.c, src/libvirt_private.syms: APIs for parsing/formatting address information. Also remove the QEMU specific 'pci_addr' attributes * src/qemu/qemu_driver.c: Replace use of 'pci_addr' attrs with new standardized format. --- docs/schemas/domain.rng | 55 +++++-- src/conf/domain_conf.c | 420 +++++++++++++++++++++++++++++++++------------- src/conf/domain_conf.h | 84 +++++----- src/libvirt_private.syms | 6 + src/qemu/qemu_driver.c | 64 ++++--- 5 files changed, 428 insertions(+), 201 deletions(-)
[...]
+int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, + int type) +{ + if (info->type != type) + return 0; + + switch (info->type) { + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI: + return virDomainDevicePCIAddressIsValid(&info->addr.pci); + }
Hum, a switch without default and not handling all cases may generate a warning with some compiler options (I find this useful when extending the union) maybe we should explicitely return 0 with _NONE
+static int +virDomainDevicePCIAddressParseXML(virConnectPtr conn, + xmlNodePtr node, + virDomainDevicePCIAddressPtr addr) +{ + char *domain, *slot, *bus, *function; + int ret = -1; + + memset(addr, 0, sizeof(*addr)); + + domain = virXMLPropString(node, "domain"); + bus = virXMLPropString(node, "bus"); + slot = virXMLPropString(node, "slot"); + function = virXMLPropString(node, "function"); + + if (domain && + virStrToLong_ui(domain, NULL, 16, &addr->domain) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse <address> 'domain' attribute")); + goto cleanup; + }
Hum, there is a small mismatch between the parsing function and the validation, virStrToLong_ uses strtol like function decoding 0 leading numbers as octal, but we don't match octal in the Relax-NG associated functions: <define name="pciDomain"> <data type="string"> <param name="pattern">(0x)?[0-9a-fA-F]{1,4}</param> </data> </define> Do we really intent to allow 0 started octal values ? I guess in octal we would need more than 4 digit to cover the address range. But it's a minor point, we could fix the RNG later ACK, the new routines are nice and the refactoring is a good cleanup ! Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Fri, Jan 15, 2010 at 01:39:18PM +0100, Daniel Veillard wrote:
On Fri, Jan 08, 2010 at 05:22:58PM +0000, Daniel P. Berrange wrote:
All guest devices now use a common device address structure summarized by:
enum virDomainDeviceAddressType { VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI, };
struct _virDomainDevicePCIAddress { unsigned int domain; unsigned int bus; unsigned int slot; unsigned int function; };
struct _virDomainDeviceInfo { int type; union { virDomainDevicePCIAddress pci; } addr; };
This replaces the anonymous structs in Disk/Net/Hostdev data structures. Where available, the address is *always* printed in the XML file, instead of being hidden in the internal state file.
<address type='pci' domain='0x0000' bus='0x1e' slot='0x07' function='0x0'/>
The structure definition is based on Wolfgang Mauerer's disk controller patch series.
* docs/schemas/domain.rng: Define the <address> syntax and associate it with disk/net/hostdev devices * src/conf/domain_conf.h, src/conf/domain_conf.c, src/libvirt_private.syms: APIs for parsing/formatting address information. Also remove the QEMU specific 'pci_addr' attributes * src/qemu/qemu_driver.c: Replace use of 'pci_addr' attrs with new standardized format. --- docs/schemas/domain.rng | 55 +++++-- src/conf/domain_conf.c | 420 +++++++++++++++++++++++++++++++++------------- src/conf/domain_conf.h | 84 +++++----- src/libvirt_private.syms | 6 + src/qemu/qemu_driver.c | 64 ++++--- 5 files changed, 428 insertions(+), 201 deletions(-)
[...]
+int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, + int type) +{ + if (info->type != type) + return 0; + + switch (info->type) { + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI: + return virDomainDevicePCIAddressIsValid(&info->addr.pci); + }
Hum, a switch without default and not handling all cases may generate a warning with some compiler options (I find this useful when extending the union) maybe we should explicitely return 0 with _NONE
+static int +virDomainDevicePCIAddressParseXML(virConnectPtr conn, + xmlNodePtr node, + virDomainDevicePCIAddressPtr addr) +{ + char *domain, *slot, *bus, *function; + int ret = -1; + + memset(addr, 0, sizeof(*addr)); + + domain = virXMLPropString(node, "domain"); + bus = virXMLPropString(node, "bus"); + slot = virXMLPropString(node, "slot"); + function = virXMLPropString(node, "function"); + + if (domain && + virStrToLong_ui(domain, NULL, 16, &addr->domain) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse <address> 'domain' attribute")); + goto cleanup; + }
Hum, there is a small mismatch between the parsing function and the validation, virStrToLong_ uses strtol like function decoding 0 leading numbers as octal, but we don't match octal in the Relax-NG associated functions:
We pass an explicit '16' to the virStrToLong_ui() so that should prevent it doing octal IIUC
<define name="pciDomain"> <data type="string"> <param name="pattern">(0x)?[0-9a-fA-F]{1,4}</param> </data> </define>
Do we really intent to allow 0 started octal values ? I guess in octal we would need more than 4 digit to cover the address range. But it's a minor point, we could fix the RNG later
My intent was for these attributes to always be interpreted as hex, no matter what, even if 0x is left off. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Fri, Jan 15, 2010 at 04:33:01PM +0000, Daniel P. Berrange wrote:
On Fri, Jan 15, 2010 at 01:39:18PM +0100, Daniel Veillard wrote:
On Fri, Jan 08, 2010 at 05:22:58PM +0000, Daniel P. Berrange wrote:
All guest devices now use a common device address structure summarized by:
enum virDomainDeviceAddressType { VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI, };
struct _virDomainDevicePCIAddress { unsigned int domain; unsigned int bus; unsigned int slot; unsigned int function; };
struct _virDomainDeviceInfo { int type; union { virDomainDevicePCIAddress pci; } addr; };
This replaces the anonymous structs in Disk/Net/Hostdev data structures. Where available, the address is *always* printed in the XML file, instead of being hidden in the internal state file.
<address type='pci' domain='0x0000' bus='0x1e' slot='0x07' function='0x0'/>
The structure definition is based on Wolfgang Mauerer's disk controller patch series.
* docs/schemas/domain.rng: Define the <address> syntax and associate it with disk/net/hostdev devices * src/conf/domain_conf.h, src/conf/domain_conf.c, src/libvirt_private.syms: APIs for parsing/formatting address information. Also remove the QEMU specific 'pci_addr' attributes * src/qemu/qemu_driver.c: Replace use of 'pci_addr' attrs with new standardized format. --- docs/schemas/domain.rng | 55 +++++-- src/conf/domain_conf.c | 420 +++++++++++++++++++++++++++++++++------------- src/conf/domain_conf.h | 84 +++++----- src/libvirt_private.syms | 6 + src/qemu/qemu_driver.c | 64 ++++--- 5 files changed, 428 insertions(+), 201 deletions(-)
[...]
+int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, + int type) +{ + if (info->type != type) + return 0; + + switch (info->type) { + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI: + return virDomainDevicePCIAddressIsValid(&info->addr.pci); + }
Hum, a switch without default and not handling all cases may generate a warning with some compiler options (I find this useful when extending the union) maybe we should explicitely return 0 with _NONE
+static int +virDomainDevicePCIAddressParseXML(virConnectPtr conn, + xmlNodePtr node, + virDomainDevicePCIAddressPtr addr) +{ + char *domain, *slot, *bus, *function; + int ret = -1; + + memset(addr, 0, sizeof(*addr)); + + domain = virXMLPropString(node, "domain"); + bus = virXMLPropString(node, "bus"); + slot = virXMLPropString(node, "slot"); + function = virXMLPropString(node, "function"); + + if (domain && + virStrToLong_ui(domain, NULL, 16, &addr->domain) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse <address> 'domain' attribute")); + goto cleanup; + }
Hum, there is a small mismatch between the parsing function and the validation, virStrToLong_ uses strtol like function decoding 0 leading numbers as octal, but we don't match octal in the Relax-NG associated functions:
We pass an explicit '16' to the virStrToLong_ui() so that should prevent it doing octal IIUC
<define name="pciDomain"> <data type="string"> <param name="pattern">(0x)?[0-9a-fA-F]{1,4}</param> </data> </define>
Do we really intent to allow 0 started octal values ? I guess in octal we would need more than 4 digit to cover the address range. But it's a minor point, we could fix the RNG later
My intent was for these attributes to always be interpreted as hex, no matter what, even if 0x is left off.
okay, I though I had looked if we included the base in the call, weird. Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Introduce a new structure struct _virDomainDeviceDriveAddress { unsigned int controller; unsigned int bus; unsigned int unit; }; and plug that into virDomainDeviceAddress and generates XML that looks like <address type='drive' controller='1' bus='0' unit='5'/> This syntax will be used by the QEMU driver to explicitly control how drives are attached to the bus * src/conf/domain_conf.h, src/conf/domain_conf.c: Parsing and formatting of drive addresses * docs/schemas/domain.rng: Define new address format for drives --- docs/schemas/domain.rng | 36 +++++++++++++++++++ src/conf/domain_conf.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++- src/conf/domain_conf.h | 13 +++++++ 3 files changed, 135 insertions(+), 1 deletions(-) diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 7e00e7f..f426587 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -1189,6 +1189,21 @@ <ref name="pciFunc"/> </attribute> </define> + <define name="driveaddress"> + <optional> + <attribute name="controller"> + <ref name="driveController"/> + </attribute> + </optional> + <optional> + <attribute name="bus"> + <ref name="driveBus"/> + </attribute> + </optional> + <attribute name="unit"> + <ref name="driveUnit"/> + </attribute> + </define> <!-- Devices attached to a domain. --> @@ -1305,6 +1320,12 @@ </attribute> <ref name="pciaddress"/> </group> + <group> + <attribute name="type"> + <value>drive</value> + </attribute> + <ref name="driveaddress"/> + </group> </choice> </element> </define> @@ -1434,6 +1455,21 @@ <param name="pattern">(0x)?[0-7]</param> </data> </define> + <define name="driveController"> + <data type="string"> + <param name="pattern">[0-9]{1,2}</param> + </data> + </define> + <define name="driveBus"> + <data type="string"> + <param name="pattern">[0-9]{1,2}</param> + </data> + </define> + <define name="driveUnit"> + <data type="string"> + <param name="pattern">[0-9]{1,2}</param> + </data> + </define> <define name="featureName"> <data type="string"> <param name='pattern'>[a-zA-Z0-9\-_]+</param> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index f199c08..d7b1aa1 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -90,7 +90,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST, VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST, "none", - "pci") + "pci", + "drive"); VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST, "block", @@ -748,6 +749,9 @@ int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, switch (info->type) { case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI: return virDomainDevicePCIAddressIsValid(&info->addr.pci); + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE: + return virDomainDeviceDriveAddressIsValid(&info->addr.drive); } return 0; @@ -760,6 +764,13 @@ int virDomainDevicePCIAddressIsValid(virDomainDevicePCIAddressPtr addr) } +int virDomainDeviceDriveAddressIsValid(virDomainDeviceDriveAddressPtr addr ATTRIBUTE_UNUSED) +{ + /*return addr->controller || addr->bus || addr->unit;*/ + return 1; /* 0 is valid for all fields, so any successfully parsed addr is valid */ +} + + int virDomainDeviceInfoIsSet(virDomainDeviceInfoPtr info) { if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) @@ -803,6 +814,13 @@ static int virDomainDeviceInfoFormat(virBufferPtr buf, info->addr.pci.function); break; + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE: + virBufferVSprintf(buf, " controller='%d' bus='%d' unit='%d'", + info->addr.drive.controller, + info->addr.drive.bus, + info->addr.drive.unit); + break; + default: virDomainReportError(NULL, VIR_ERR_INTERNAL_ERROR, _("unknown address type '%d'"), info->type); @@ -828,6 +846,18 @@ int virDomainDevicePCIAddressEqual(virDomainDevicePCIAddressPtr a, } +int virDomainDeviceDriveAddressEqual(virDomainDeviceDriveAddressPtr a, + virDomainDeviceDriveAddressPtr b) +{ + if (a->controller == b->controller && + a->bus == b->bus && + a->unit == b->unit) + return 1; + + return 0; +} + + static int virDomainDevicePCIAddressParseXML(virConnectPtr conn, xmlNodePtr node, @@ -888,6 +918,56 @@ cleanup: } +static int +virDomainDeviceDriveAddressParseXML(virConnectPtr conn, + xmlNodePtr node, + virDomainDeviceDriveAddressPtr addr) +{ + char *bus, *unit, *controller; + int ret = -1; + + memset(addr, 0, sizeof(*addr)); + + controller = virXMLPropString(node, "controller"); + bus = virXMLPropString(node, "bus"); + unit = virXMLPropString(node, "unit"); + + if (controller && + virStrToLong_ui(controller, NULL, 10, &addr->controller) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse <address> 'controller' attribute")); + goto cleanup; + } + + if (bus && + virStrToLong_ui(bus, NULL, 10, &addr->bus) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse <address> 'bus' attribute")); + goto cleanup; + } + + if (unit && + virStrToLong_ui(unit, NULL, 10, &addr->unit) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse <address> 'unit' attribute")); + goto cleanup; + } + + if (!virDomainDeviceDriveAddressIsValid(addr)) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Insufficient specification for drive address")); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FREE(controller); + VIR_FREE(bus); + VIR_FREE(unit); + return ret; +} + /* Parse the XML definition for a device address * @param node XML nodeset to parse for device address definition */ @@ -938,6 +1018,11 @@ virDomainDeviceInfoParseXML(virConnectPtr conn, goto cleanup; break; + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE: + if (virDomainDeviceDriveAddressParseXML(conn, node, &info->addr.drive) < 0) + goto cleanup; + break; + default: /* Should not happen */ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index c50aae0..d4de042 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -67,6 +67,7 @@ enum virDomainVirtType { enum virDomainDeviceAddressType { VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI, + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST }; @@ -80,12 +81,21 @@ struct _virDomainDevicePCIAddress { unsigned int function; }; +typedef struct _virDomainDeviceDriveAddress virDomainDeviceDriveAddress; +typedef virDomainDeviceDriveAddress *virDomainDeviceDriveAddressPtr; +struct _virDomainDeviceDriveAddress { + unsigned int controller; + unsigned int bus; + unsigned int unit; +}; + typedef struct _virDomainDeviceInfo virDomainDeviceInfo; typedef virDomainDeviceInfo *virDomainDeviceInfoPtr; struct _virDomainDeviceInfo { int type; union { virDomainDevicePCIAddress pci; + virDomainDeviceDriveAddress drive; } addr; }; @@ -690,9 +700,12 @@ void virDomainHostdevDefFree(virDomainHostdevDefPtr def); void virDomainDeviceDefFree(virDomainDeviceDefPtr def); int virDomainDevicePCIAddressEqual(virDomainDevicePCIAddressPtr a, virDomainDevicePCIAddressPtr b); +int virDomainDeviceDriveAddressEqual(virDomainDeviceDriveAddressPtr a, + virDomainDeviceDriveAddressPtr b); int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info, int type); int virDomainDevicePCIAddressIsValid(virDomainDevicePCIAddressPtr addr); +int virDomainDeviceDriveAddressIsValid(virDomainDeviceDriveAddressPtr addr); int virDomainDeviceInfoIsSet(virDomainDeviceInfoPtr info); void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info); void virDomainDefFree(virDomainDefPtr vm); -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:22:59PM +0000, Daniel P. Berrange wrote:
Introduce a new structure
struct _virDomainDeviceDriveAddress { unsigned int controller; unsigned int bus; unsigned int unit; };
and plug that into virDomainDeviceAddress and generates XML that looks like
<address type='drive' controller='1' bus='0' unit='5'/>
This syntax will be used by the QEMU driver to explicitly control how drives are attached to the bus
* src/conf/domain_conf.h, src/conf/domain_conf.c: Parsing and formatting of drive addresses * docs/schemas/domain.rng: Define new address format for drives [...] @@ -1434,6 +1455,21 @@ <param name="pattern">(0x)?[0-7]</param> </data> </define> + <define name="driveController"> + <data type="string"> + <param name="pattern">[0-9]{1,2}</param> + </data> + </define> + <define name="driveBus"> + <data type="string"> + <param name="pattern">[0-9]{1,2}</param> + </data> + </define> + <define name="driveUnit"> + <data type="string"> + <param name="pattern">[0-9]{1,2}</param> + </data> + </define> <define name="featureName"> <data type="string"> <param name='pattern'>[a-zA-Z0-9\-_]+</param> [...] +static int +virDomainDeviceDriveAddressParseXML(virConnectPtr conn, + xmlNodePtr node, + virDomainDeviceDriveAddressPtr addr) +{ + char *bus, *unit, *controller; + int ret = -1; + + memset(addr, 0, sizeof(*addr)); + + controller = virXMLPropString(node, "controller"); + bus = virXMLPropString(node, "bus"); + unit = virXMLPropString(node, "unit"); + + if (controller && + virStrToLong_ui(controller, NULL, 10, &addr->controller) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse <address> 'controller' attribute")); + goto cleanup; + } + + if (bus && + virStrToLong_ui(bus, NULL, 10, &addr->bus) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse <address> 'bus' attribute")); + goto cleanup; + } + + if (unit && + virStrToLong_ui(unit, NULL, 10, &addr->unit) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot parse <address> 'unit' attribute")); + goto cleanup; + }
There is also a mismatch here, as the RNG will allow only values 0-99 and the parsing will allow any unsigned decimal. But again that's not a blocker, the issue could be fixed later, just keep a comment somewhere about the todo on the parser side. ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Add the virDomainDeviceAddress information to the sound, video and watchdog devices. This means all of them gain the new XML element <address .... /> This brings them upto par with disk/net/hostdev devices which already have address info * src/conf/domain_conf.h: Add virDomainDeviceAddress to sound, video & watchdog device struts. * src/conf/domain_conf.c: Hook up parsing/formatting for virDomainDeviceAddress in sound, video & watchdog devices * docs/schemas/domain.rng: Associate device address info with sound, video & watchdog --- docs/schemas/domain.rng | 9 +++++++ src/conf/domain_conf.c | 54 +++++++++++++++++++++++++++++++++++++++------- src/conf/domain_conf.h | 3 ++ 3 files changed, 57 insertions(+), 9 deletions(-) diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index f426587..dd729c0 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -907,6 +907,9 @@ </optional> </element> </optional> + <optional> + <ref name="address"/> + </optional> </element> </define> <!-- @@ -1043,6 +1046,9 @@ <value>ac97</value> </choice> </attribute> + <optional> + <ref name="address"/> + </optional> </element> </define> <define name="watchdog"> @@ -1064,6 +1070,9 @@ </choice> </attribute> </optional> + <optional> + <ref name="address"/> + </optional> </element> </define> <define name="parallel"> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d7b1aa1..27d0613 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -465,6 +465,8 @@ void virDomainSoundDefFree(virDomainSoundDefPtr def) if (!def) return; + virDomainDeviceInfoClear(&def->info); + VIR_FREE(def); } @@ -473,6 +475,8 @@ void virDomainWatchdogDefFree(virDomainWatchdogDefPtr def) if (!def) return; + virDomainDeviceInfoClear(&def->info); + VIR_FREE(def); } @@ -481,6 +485,8 @@ void virDomainVideoDefFree(virDomainVideoDefPtr def) if (!def) return; + virDomainDeviceInfoClear(&def->info); + VIR_FREE(def->accel); VIR_FREE(def); } @@ -2259,8 +2265,8 @@ error: static virDomainSoundDefPtr virDomainSoundDefParseXML(virConnectPtr conn, const xmlNodePtr node, - int flags ATTRIBUTE_UNUSED) { - + int flags) +{ char *model; virDomainSoundDefPtr def; @@ -2276,6 +2282,9 @@ virDomainSoundDefParseXML(virConnectPtr conn, goto error; } + if (virDomainDeviceInfoParseXML(conn, node, &def->info, flags) < 0) + goto error; + cleanup: VIR_FREE(model); @@ -2291,7 +2300,8 @@ error: static virDomainWatchdogDefPtr virDomainWatchdogDefParseXML(virConnectPtr conn, const xmlNodePtr node, - int flags ATTRIBUTE_UNUSED) { + int flags) +{ char *model = NULL; char *action = NULL; @@ -2327,6 +2337,9 @@ virDomainWatchdogDefParseXML(virConnectPtr conn, } } + if (virDomainDeviceInfoParseXML(conn, node, &def->info, flags) < 0) + goto error; + cleanup: VIR_FREE (action); VIR_FREE (model); @@ -2439,7 +2452,7 @@ static virDomainVideoDefPtr virDomainVideoDefParseXML(virConnectPtr conn, const xmlNodePtr node, virDomainDefPtr dom, - int flags ATTRIBUTE_UNUSED) { + int flags) { virDomainVideoDefPtr def; xmlNodePtr cur; char *type = NULL; @@ -2499,6 +2512,9 @@ virDomainVideoDefParseXML(virConnectPtr conn, def->heads = 1; } + if (virDomainDeviceInfoParseXML(conn, node, &def->info, flags) < 0) + goto error; + VIR_FREE(type); VIR_FREE(vram); VIR_FREE(heads); @@ -2927,8 +2943,7 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virConnectPtr conn, goto error; } else if (xmlStrEqual(node->name, BAD_CAST "watchdog")) { dev->type = VIR_DOMAIN_DEVICE_WATCHDOG; - if (!(dev->data.watchdog = virDomainWatchdogDefParseXML(conn, node, - flags))) + if (!(dev->data.watchdog = virDomainWatchdogDefParseXML(conn, node, flags))) goto error; } else if (xmlStrEqual(node->name, BAD_CAST "video")) { dev->type = VIR_DOMAIN_DEVICE_VIDEO; @@ -3637,7 +3652,7 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn, } if (n > 0) { virDomainWatchdogDefPtr watchdog = - virDomainWatchdogDefParseXML (conn, nodes[0], flags); + virDomainWatchdogDefParseXML(conn, nodes[0], flags); if (!watchdog) goto error; @@ -4550,9 +4565,18 @@ virDomainSoundDefFormat(virConnectPtr conn, return -1; } - virBufferVSprintf(buf, " <sound model='%s'/>\n", + virBufferVSprintf(buf, " <sound model='%s'", model); + if (virDomainDeviceInfoIsSet(&def->info)) { + virBufferAddLit(buf, ">\n"); + if (virDomainDeviceInfoFormat(buf, &def->info) < 0) + return -1; + virBufferAddLit(buf, " </sound>\n"); + } else { + virBufferAddLit(buf, "/>\n"); + } + return 0; } @@ -4577,9 +4601,18 @@ virDomainWatchdogDefFormat(virConnectPtr conn, return -1; } - virBufferVSprintf(buf, " <watchdog model='%s' action='%s'/>\n", + virBufferVSprintf(buf, " <watchdog model='%s' action='%s'", model, action); + if (virDomainDeviceInfoIsSet(&def->info)) { + virBufferAddLit(buf, ">\n"); + if (virDomainDeviceInfoFormat(buf, &def->info) < 0) + return -1; + virBufferAddLit(buf, " </watchdog>\n"); + } else { + virBufferAddLit(buf, "/>\n"); + } + return 0; } @@ -4624,6 +4657,9 @@ virDomainVideoDefFormat(virConnectPtr conn, virBufferAddLit(buf, "/>\n"); } + if (virDomainDeviceInfoFormat(buf, &def->info) < 0) + return -1; + virBufferAddLit(buf, " </video>\n"); return 0; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index d4de042..0f68864 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -335,6 +335,7 @@ typedef struct _virDomainSoundDef virDomainSoundDef; typedef virDomainSoundDef *virDomainSoundDefPtr; struct _virDomainSoundDef { int model; + virDomainDeviceInfo info; }; enum virDomainWatchdogModel { @@ -359,6 +360,7 @@ typedef virDomainWatchdogDef *virDomainWatchdogDefPtr; struct _virDomainWatchdogDef { int model; int action; + virDomainDeviceInfo info; }; @@ -388,6 +390,7 @@ struct _virDomainVideoDef { unsigned int vram; unsigned int heads; virDomainVideoAccelDefPtr accel; + virDomainDeviceInfo info; }; /* 3 possible graphics console modes */ -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:00PM +0000, Daniel P. Berrange wrote:
Add the virDomainDeviceAddress information to the sound, video and watchdog devices. This means all of them gain the new XML element
<address .... />
This brings them upto par with disk/net/hostdev devices which already have address info
* src/conf/domain_conf.h: Add virDomainDeviceAddress to sound, video & watchdog device struts. * src/conf/domain_conf.c: Hook up parsing/formatting for virDomainDeviceAddress in sound, video & watchdog devices * docs/schemas/domain.rng: Associate device address info with sound, video & watchdog --- docs/schemas/domain.rng | 9 +++++++ src/conf/domain_conf.c | 54 +++++++++++++++++++++++++++++++++++++++------- src/conf/domain_conf.h | 3 ++ 3 files changed, 57 insertions(+), 9 deletions(-)
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

When parsing the <disk> element specification, if no <address> is provided for the disk, then automatically assign one based on the <target dev='sdXX'/> device name. This provides for backwards compatability with existing applications using libvirt, while also allowing new apps to have complete fine grained control. * src/conf/domain_conf.h, src/conf/domain_conf.c, src/libvirt_private.syms: Add virDomainDiskDefAssignAddress() for assigning a controller/bus/unit address based on disk target * src/qemu/qemu_conf.c: Call virDomainDiskDefAssignAddress() after generating XML from ARGV * tests/qemuxml2argvdata/*.xml: Add in drive address information to all XML files --- src/conf/domain_conf.c | 44 +++++++++++++++++++- src/conf/domain_conf.h | 1 + src/libvirt_private.syms | 1 + src/qemu/qemu_conf.c | 4 ++ tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml | 1 + .../qemuxml2argvdata/qemuxml2argv-boot-floppy.xml | 2 + .../qemuxml2argvdata/qemuxml2argv-boot-network.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml | 1 + .../qemuxml2argv-channel-guestfwd.xml | 1 + .../qemuxml2argv-clock-localtime.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-clock-utc.xml | 1 + .../qemuxml2argv-console-compat-chardev.xml | 1 + .../qemuxml2argv-console-compat.xml | 1 + .../qemuxml2argv-disk-cdrom-empty.xml | 2 + tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml | 2 + .../qemuxml2argv-disk-drive-boot-cdrom.xml | 2 + .../qemuxml2argv-disk-drive-boot-disk.xml | 2 + .../qemuxml2argv-disk-drive-cache-v1-none.xml | 2 + .../qemuxml2argv-disk-drive-cache-v1-wb.xml | 2 + .../qemuxml2argv-disk-drive-cache-v1-wt.xml | 2 + .../qemuxml2argv-disk-drive-cache-v2-none.xml | 2 + .../qemuxml2argv-disk-drive-cache-v2-wb.xml | 2 + .../qemuxml2argv-disk-drive-cache-v2-wt.xml | 2 + .../qemuxml2argv-disk-drive-fat.xml | 1 + .../qemuxml2argv-disk-drive-fmt-qcow.xml | 2 + .../qemuxml2argv-disk-drive-shared.xml | 2 + .../qemuxml2argvdata/qemuxml2argv-disk-floppy.xml | 3 + tests/qemuxml2argvdata/qemuxml2argv-disk-many.xml | 4 ++ tests/qemuxml2argvdata/qemuxml2argv-disk-usb.xml | 1 + .../qemuxml2argvdata/qemuxml2argv-disk-virtio.xml | 3 + .../qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml | 2 + .../qemuxml2argv-floppy-drive-fat.xml | 1 + .../qemuxml2argv-graphics-sdl-fullscreen.xml | 1 + .../qemuxml2argvdata/qemuxml2argv-graphics-sdl.xml | 1 + .../qemuxml2argv-graphics-vnc-sasl.xml | 1 + .../qemuxml2argv-graphics-vnc-tls.xml | 1 + .../qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml | 1 + .../qemuxml2argv-hostdev-pci-address.xml | 1 + .../qemuxml2argv-hostdev-usb-address.xml | 1 + .../qemuxml2argv-hostdev-usb-product.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-hugepages.xml | 1 + .../qemuxml2argv-input-usbmouse.xml | 1 + .../qemuxml2argv-input-usbtablet.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml | 1 + .../qemuxml2argv-machine-aliases1.xml | 1 + .../qemuxml2argv-machine-aliases2.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-migrate.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-minimal.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.xml | 1 + .../qemuxml2argv-misc-no-reboot.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-misc-uuid.xml | 1 + .../qemuxml2argv-net-eth-ifname.xml | 1 + .../qemuxml2argv-net-eth-names.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-net-eth.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-net-user.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-net-virtio.xml | 1 + .../qemuxml2argv-parallel-tcp-chardev.xml | 1 + .../qemuxml2argvdata/qemuxml2argv-parallel-tcp.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-restore-v1.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-restore-v2.xml | 1 + .../qemuxml2argv-serial-dev-chardev.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-serial-dev.xml | 1 + .../qemuxml2argv-serial-file-chardev.xml | 1 + .../qemuxml2argvdata/qemuxml2argv-serial-file.xml | 1 + .../qemuxml2argv-serial-many-chardev.xml | 1 + .../qemuxml2argvdata/qemuxml2argv-serial-many.xml | 1 + .../qemuxml2argv-serial-pty-chardev.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-serial-pty.xml | 1 + .../qemuxml2argv-serial-tcp-chardev.xml | 1 + .../qemuxml2argv-serial-tcp-telnet-chardev.xml | 1 + .../qemuxml2argv-serial-tcp-telnet.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.xml | 1 + .../qemuxml2argv-serial-udp-chardev.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml | 1 + .../qemuxml2argv-serial-unix-chardev.xml | 1 + .../qemuxml2argvdata/qemuxml2argv-serial-unix.xml | 1 + .../qemuxml2argv-serial-vc-chardev.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-serial-vc.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-sound.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-watchdog.xml | 1 + tests/qemuxml2xmltest.c | 1 + 81 files changed, 147 insertions(+), 1 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 27d0613..662ff81 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1025,7 +1025,7 @@ virDomainDeviceInfoParseXML(virConnectPtr conn, break; case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE: - if (virDomainDeviceDriveAddressParseXML(conn, node, &info->addr.drive) < 0) + if (virDomainDeviceDriveAddressParseXML(conn, address, &info->addr.drive) < 0) goto cleanup; break; @@ -1044,6 +1044,45 @@ cleanup: } +void +virDomainDiskDefAssignAddress(virDomainDiskDefPtr def) +{ + int idx = virDiskNameToIndex(def->dst); + + switch (def->bus) { + case VIR_DOMAIN_DISK_BUS_SCSI: + /* For SCSI we define the default mapping to be 7 units + * per bus, 1 bus per controller, many controllers */ + def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE; + def->info.addr.drive.controller = idx / 7; + def->info.addr.drive.bus = 0; + def->info.addr.drive.unit = idx % 7; + break; + + case VIR_DOMAIN_DISK_BUS_IDE: + /* For IDE we define the default mapping to be 2 units + * per bus, 2 bus per controller, many controllers */ + def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE; + def->info.addr.drive.controller = idx / 4; + def->info.addr.drive.bus = (idx % 4) / 2; + def->info.addr.drive.unit = (idx % 2); + break; + + case VIR_DOMAIN_DISK_BUS_FDC: + /* For FDC we define the default mapping to be 2 units + * per bus, 1 bus per controller, many controllers */ + def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE; + def->info.addr.drive.controller = idx / 2; + def->info.addr.drive.bus = 0; + def->info.addr.drive.unit = idx % 2; + break; + + default: + /* Other disk bus's aren't controller based */ + break; + } +} + /* Parse the XML definition for a disk * @param node XML nodeset to parse for disk definition */ @@ -1271,6 +1310,9 @@ virDomainDiskDefParseXML(virConnectPtr conn, def->serial = serial; serial = NULL; + if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + virDomainDiskDefAssignAddress(def); + cleanup: VIR_FREE(bus); VIR_FREE(type); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 0f68864..a05835a 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -773,6 +773,7 @@ int virDomainDiskInsert(virDomainDefPtr def, virDomainDiskDefPtr disk); void virDomainDiskInsertPreAlloced(virDomainDefPtr def, virDomainDiskDefPtr disk); +void virDomainDiskDefAssignAddress(virDomainDiskDefPtr def); int virDomainSaveXML(virConnectPtr conn, const char *configDir, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 67ffe69..9a4f444 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -129,6 +129,7 @@ virDomainDiskDefFree; virDomainDiskDeviceTypeToString; virDomainDiskInsert; virDomainDiskInsertPreAlloced; +virDomainDiskDefAssignAddress; virDomainFindByID; virDomainFindByName; virDomainFindByUUID; diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 824055f..c575d63 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -3270,6 +3270,8 @@ qemuParseCommandLineDisk(virConnectPtr conn, else def->dst[2] = 'a' + idx; + virDomainDiskDefAssignAddress(def); + cleanup: for (i = 0 ; i < nkeywords ; i++) { VIR_FREE(keywords[i]); @@ -3999,6 +4001,8 @@ virDomainDefPtr qemuParseCommandLine(virConnectPtr conn, goto no_memory; } + virDomainDiskDefAssignAddress(disk); + if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0) { virDomainDiskDefFree(disk); goto no_memory; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml index 5211d0c..6915145 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml @@ -18,6 +18,7 @@ <source dev='/dev/cdrom'/> <target dev='hdc' bus='ide'/> <readonly/> + <address type='drive' controller='0' bus='1' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml index ad33b53..0b6b084 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml @@ -17,10 +17,12 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='file' device='floppy'> <source file='/tmp/firmware.img'/> <target dev='fda' bus='fdc'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-network.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-network.xml index 8d510a9..4de216e 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-network.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-network.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml b/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml index e28709e..0501fd4 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml @@ -18,6 +18,7 @@ <source dev='/dev/cdrom'/> <target dev='hdc' bus='ide'/> <readonly/> + <address type='drive' controller='0' bus='1' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.xml b/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.xml index 51a0c1e..aeba5be 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <channel type='pipe'> <source path='/tmp/guestfwd'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime.xml b/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime.xml index dc1ae32..1db0d02 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-clock-utc.xml b/tests/qemuxml2argvdata/qemuxml2argv-clock-utc.xml index 26c9b25..9e9153f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-clock-utc.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-utc.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.xml index c16ae07..1f8f126 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='pty'> <target port='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-compat.xml b/tests/qemuxml2argvdata/qemuxml2argv-console-compat.xml index c16ae07..1f8f126 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-console-compat.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-console-compat.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='pty'> <target port='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml index d5341b3..ff315e1 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml @@ -17,10 +17,12 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='file' device='cdrom'> <target dev='hdc' bus='ide'/> <readonly/> + <address type='drive' controller='0' bus='1' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml index 550136d..097d3dd 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml @@ -17,11 +17,13 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='file' device='cdrom'> <source file='/root/boot.iso'/> <target dev='hdc' bus='ide'/> <readonly/> + <address type='drive' controller='0' bus='1' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.xml index fdbf2b8..743e996 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.xml @@ -17,10 +17,12 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/QEMUGuest2'/> <target dev='hdc' bus='ide'/> + <address type='drive' controller='0' bus='1' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.xml index b8ff06a..c1d3f4a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.xml @@ -17,10 +17,12 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/QEMUGuest2'/> <target dev='hdc' bus='ide'/> + <address type='drive' controller='0' bus='1' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.xml index 4603ce5..706b6e2 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.xml @@ -18,12 +18,14 @@ <driver name='qemu' type='qcow2' cache='none'/> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> <target dev='hdc' bus='ide'/> <readonly/> + <address type='drive' controller='0' bus='1' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.xml index 97fc09e..4d3fb0c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.xml @@ -18,12 +18,14 @@ <driver name='qemu' type='qcow2' cache='writeback'/> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> <target dev='hdc' bus='ide'/> <readonly/> + <address type='drive' controller='0' bus='1' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.xml index d26005f..b81f1a4 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.xml @@ -18,12 +18,14 @@ <driver name='qemu' type='qcow2' cache='writethrough'/> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> <target dev='hdc' bus='ide'/> <readonly/> + <address type='drive' controller='0' bus='1' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.xml index 4603ce5..706b6e2 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.xml @@ -18,12 +18,14 @@ <driver name='qemu' type='qcow2' cache='none'/> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> <target dev='hdc' bus='ide'/> <readonly/> + <address type='drive' controller='0' bus='1' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.xml index 97fc09e..4d3fb0c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.xml @@ -18,12 +18,14 @@ <driver name='qemu' type='qcow2' cache='writeback'/> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> <target dev='hdc' bus='ide'/> <readonly/> + <address type='drive' controller='0' bus='1' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.xml index d26005f..b81f1a4 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.xml @@ -18,12 +18,14 @@ <driver name='qemu' type='qcow2' cache='writethrough'/> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> <target dev='hdc' bus='ide'/> <readonly/> + <address type='drive' controller='0' bus='1' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.xml index 818ca93..0a13d19 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.xml @@ -19,6 +19,7 @@ <source dir='/var/somefiles'/> <target dev='hda' bus='ide'/> <readonly/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.xml index 2537da6..5c1d456 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.xml @@ -18,12 +18,14 @@ <driver name='qemu' type='qcow2'/> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> <target dev='hdc' bus='ide'/> <readonly/> + <address type='drive' controller='0' bus='1' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml index c4e4734..774decd 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml @@ -20,12 +20,14 @@ <target dev='hda' bus='ide'/> <shareable/> <serial>XYZXYZXYZYXXYZYZYXYZY</serial> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='block' device='cdrom'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'/> <target dev='hdc' bus='ide'/> <readonly/> + <address type='drive' controller='0' bus='1' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml index 9debdf4..37d178d 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml @@ -17,14 +17,17 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='block' device='floppy'> <source dev='/dev/fd0'/> <target dev='fda' bus='fdc'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='file' device='floppy'> <source file='/tmp/firmware.img'/> <target dev='fdb' bus='fdc'/> + <address type='drive' controller='0' bus='0' unit='1'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-many.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-many.xml index 4abe883..6f9b705 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-many.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-many.xml @@ -17,18 +17,22 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest2'/> <target dev='hdb' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='1'/> </disk> <disk type='file' device='disk'> <source file='/tmp/data.img'/> <target dev='hdc' bus='ide'/> + <address type='drive' controller='0' bus='1' unit='0'/> </disk> <disk type='file' device='disk'> <source file='/tmp/logs.img'/> <target dev='hdd' bus='ide'/> + <address type='drive' controller='0' bus='1' unit='1'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-usb.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-usb.xml index d59e1c0..3b86a11 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-usb.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-usb.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='file' device='disk'> <source file='/tmp/usbdisk.img'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml index bda4455..e506d9f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml @@ -17,10 +17,13 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/QEMUGuest2'/> <target dev='hdc' bus='ide'/> + <readonly/> + <address type='drive' controller='0' bus='1' unit='0'/> </disk> <disk type='file' device='disk'> <source file='/tmp/data.img'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml index c42404a..17cc408 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml @@ -17,11 +17,13 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='block' device='cdrom'> <source dev='/dev/HostVG/QEMUGuest2'/> <target dev='hdc' bus='ide'/> <readonly/> + <address type='drive' controller='0' bus='1' unit='0'/> </disk> <disk type='file' device='disk'> <source file='/tmp/data.img'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml b/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml index 9e32b68..7bc09fa 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml @@ -19,6 +19,7 @@ <source dir='/var/somefiles'/> <target dev='fda' bus='fdc'/> <readonly/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl-fullscreen.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl-fullscreen.xml index f3fc588..8508be5 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl-fullscreen.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl-fullscreen.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <input type='mouse' bus='ps2'/> <graphics type='sdl' display=':0.1' xauth='/root/.Xauthority' fullscreen='yes'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl.xml index 431c3c9..c83587b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <input type='mouse' bus='ps2'/> <graphics type='sdl' display=':0.1' xauth='/root/.Xauthority'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.xml index b6f99d3..15b561f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <input type='mouse' bus='ps2'/> <graphics type='vnc' port='5903' autoport='no' listen='127.0.0.1'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.xml index b6f99d3..15b561f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <input type='mouse' bus='ps2'/> <graphics type='vnc' port='5903' autoport='no' listen='127.0.0.1'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml index b6f99d3..15b561f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <input type='mouse' bus='ps2'/> <graphics type='vnc' port='5903' autoport='no' listen='127.0.0.1'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml index ac5ad47..7c7e548 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest2'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <hostdev mode='subsystem' type='pci' managed='yes'> <source> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address.xml index 61bb2a2..08d78e6 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <hostdev mode='subsystem' type='usb' managed='no'> <source> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-product.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-product.xml index 6cb1ba1..85a822b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-product.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-product.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <hostdev mode='subsystem' type='usb' managed='no'> <source> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hugepages.xml b/tests/qemuxml2argvdata/qemuxml2argv-hugepages.xml index e25286f..92f2c47 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hugepages.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-hugepages.xml @@ -20,6 +20,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.xml b/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.xml index 573015b..d036eb4 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <input type='mouse' bus='usb'/> </devices> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.xml b/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.xml index ea5769a..82fd363 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <input type='tablet' bus='usb'/> </devices> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml b/tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml index fea7f8e..9976a56 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <input type='mouse' bus='xen'/> <graphics type='vnc' port='5903' autoport='no' listen='127.0.0.1'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.xml b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.xml index 039abfd..eca3a6f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml index a2c6254..b50e409 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-migrate.xml b/tests/qemuxml2argvdata/qemuxml2argv-migrate.xml index 26c9b25..9e9153f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-migrate.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-migrate.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-minimal.xml b/tests/qemuxml2argvdata/qemuxml2argv-minimal.xml index 566a4ad..78b578b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-minimal.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-minimal.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.xml b/tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.xml index 1b37bdc..fe0a00e 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.xml @@ -20,6 +20,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-misc-no-reboot.xml b/tests/qemuxml2argvdata/qemuxml2argv-misc-no-reboot.xml index dc6193d..2c53078 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-misc-no-reboot.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-misc-no-reboot.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-misc-uuid.xml b/tests/qemuxml2argvdata/qemuxml2argv-misc-uuid.xml index 1b37bdc..fe0a00e 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-misc-uuid.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-misc-uuid.xml @@ -20,6 +20,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-eth-ifname.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-eth-ifname.xml index 9ca4295..08aaa35 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-net-eth-ifname.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-eth-ifname.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <interface type='ethernet'> <mac address='00:11:22:33:44:55'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.xml index 8aae269..c52d55b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <interface type='ethernet'> <mac address='00:11:22:33:44:55'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-eth.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-eth.xml index 5856c3d..9aba26e 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-net-eth.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-eth.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <interface type='ethernet'> <mac address='00:11:22:33:44:55'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-user.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-user.xml index 630673a..3abda1c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-net-user.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-user.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <interface type='user'> <mac address='00:11:22:33:44:55'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio.xml index 5d34bd4..4eac686 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <interface type='user'> <mac address='00:11:22:33:44:55'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.xml index 08176f1..ab675b6 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <parallel type='tcp'> <source mode='bind' host='127.0.0.1' service='9999'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp.xml b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp.xml index 08176f1..ab675b6 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <parallel type='tcp'> <source mode='bind' host='127.0.0.1' service='9999'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-restore-v1.xml b/tests/qemuxml2argvdata/qemuxml2argv-restore-v1.xml index 26c9b25..9e9153f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-restore-v1.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-restore-v1.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-restore-v2.xml b/tests/qemuxml2argvdata/qemuxml2argv-restore-v2.xml index 26c9b25..9e9153f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-restore-v2.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-restore-v2.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.xml index 2b8ef5a..06c40e8 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='dev'> <source path='/dev/ttyS2'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-dev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev.xml index 2b8ef5a..06c40e8 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-dev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='dev'> <source path='/dev/ttyS2'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.xml index 3726816..7c2cc03 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='file'> <source path='/tmp/serial.log'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-file.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-file.xml index 3726816..7c2cc03 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-file.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-file.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='file'> <source path='/tmp/serial.log'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.xml index 444e85b..4021129 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='pty'> <target port='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-many.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-many.xml index 444e85b..4021129 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-many.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-many.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='pty'> <target port='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.xml index c16ae07..1f8f126 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='pty'> <target port='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-pty.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty.xml index c16ae07..1f8f126 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-pty.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='pty'> <target port='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.xml index 3bcf62d..5d14515 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='tcp'> <source mode='connect' host='127.0.0.1' service='9999'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.xml index bea4306..1f940db 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='tcp'> <source mode='bind' host='127.0.0.1' service='9999'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet.xml index bea4306..1f940db 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='tcp'> <source mode='bind' host='127.0.0.1' service='9999'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.xml index 3bcf62d..5d14515 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='tcp'> <source mode='connect' host='127.0.0.1' service='9999'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.xml index 115166d..addf093 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='udp'> <source mode='bind' host='127.0.0.1' service='9999'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml index 115166d..addf093 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='udp'> <source mode='bind' host='127.0.0.1' service='9999'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.xml index 4236b4c..81884a1 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='unix'> <source mode='connect' path='/tmp/serial.sock'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-unix.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix.xml index 4236b4c..81884a1 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-unix.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='unix'> <source mode='connect' path='/tmp/serial.sock'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.xml index 1e5de8f..0a1980c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='vc'> <target port='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-vc.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc.xml index 1e5de8f..0a1980c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-vc.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <serial type='vc'> <target port='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-sound.xml b/tests/qemuxml2argvdata/qemuxml2argv-sound.xml index 8c33e6c..3327c19 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-sound.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-sound.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <sound model='pcspk'/> <sound model='es1370'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-watchdog.xml b/tests/qemuxml2argvdata/qemuxml2argv-watchdog.xml index 9b2ffdf..52ff117 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-watchdog.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-watchdog.xml @@ -17,6 +17,7 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> <watchdog model='ib700' action='poweroff'/> </devices> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index e5900a2..0302696 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -98,6 +98,7 @@ mymain(int argc, char **argv) DO_TEST("disk-many"); DO_TEST("disk-xenvbd"); DO_TEST("disk-usb"); + DO_TEST("disk-virtio"); DO_TEST("floppy-drive-fat"); DO_TEST("disk-drive-fat"); DO_TEST("disk-drive-fmt-qcow"); -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:01PM +0000, Daniel P. Berrange wrote:
When parsing the <disk> element specification, if no <address> is provided for the disk, then automatically assign one based on the <target dev='sdXX'/> device name. This provides for backwards compatability with existing applications using libvirt, while also allowing new apps to have complete fine grained control.
* src/conf/domain_conf.h, src/conf/domain_conf.c, src/libvirt_private.syms: Add virDomainDiskDefAssignAddress() for assigning a controller/bus/unit address based on disk target * src/qemu/qemu_conf.c: Call virDomainDiskDefAssignAddress() after generating XML from ARGV * tests/qemuxml2argvdata/*.xml: Add in drive address information to all XML files
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

From: Wolfgang Mauerer <wolfgang.mauerer@siemens.com> This augments virDomainDevice with a <controller> element that is used to represent disk controllers (e.g., scsi controllers). The XML format is given by <controller type="scsi" index="<num>"> <address type="pci" domain="0xNUM" bus="0xNUM" slot="0xNUM"/> </controller> where type denotes the disk interface (scsi, ide,...), index is an integer that identifies the controller for association with disks, and the <address> element specifies the controller address on the PCI bus as described in previous commits The address element can be omitted; in this case, an address will be assigned automatically. Most of the code in this patch is from Wolfgang Mauerer's previous disk controller series * docs/schemas/domain.rng: Define syntax for <controller> XML element * src/conf/domain_conf.c, src/conf/domain_conf.h: Define virDomainControllerDef struct, and routines for parsing and formatting XML * src/libvirt_private.syms: Add virDomainControllerInsert and virDomainControllerDefFree --- docs/schemas/domain.rng | 20 +++++ src/conf/domain_conf.c | 192 +++++++++++++++++++++++++++++++++++++++++++++- src/conf/domain_conf.h | 31 ++++++++ src/libvirt_private.syms | 2 + 4 files changed, 244 insertions(+), 1 deletions(-) diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index dd729c0..a32ce45 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -521,6 +521,25 @@ </choice> </attribute> </define> + <define name="controller"> + <element name="controller"> + <optional> + <attribute name="type"> + <choice> + <value>fdc</value> + <value>ide</value> + <value>scsi</value> + </choice> + </attribute> + </optional> + <attribute name="index"> + <ref name="unsignedInt"/> + </attribute> + <optional> + <ref name="address"/> + </optional> + </element> + </define> <define name="filesystem"> <element name="filesystem"> <choice> @@ -1225,6 +1244,7 @@ <zeroOrMore> <choice> <ref name="disk"/> + <ref name="controller"/> <ref name="filesystem"/> <ref name="interface"/> <ref name="input"/> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 662ff81..dd10f36 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -86,7 +86,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST, "sound", "video", "hostdev", - "watchdog") + "watchdog", + "controller") VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST, "none", @@ -119,6 +120,12 @@ VIR_ENUM_IMPL(virDomainDiskCache, VIR_DOMAIN_DISK_CACHE_LAST, "writethrough", "writeback") +VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST, + "ide", + "fdc", + "scsi", + "sata") + VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST, "mount", "block", @@ -367,6 +374,16 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def) VIR_FREE(def); } +void virDomainControllerDefFree(virDomainControllerDefPtr def) +{ + if (!def) + return; + + virDomainDeviceInfoClear(&def->info); + + VIR_FREE(def); +} + void virDomainFSDefFree(virDomainFSDefPtr def) { if (!def) @@ -528,6 +545,9 @@ void virDomainDeviceDefFree(virDomainDeviceDefPtr def) case VIR_DOMAIN_DEVICE_WATCHDOG: virDomainWatchdogDefFree(def->data.watchdog); break; + case VIR_DOMAIN_DEVICE_CONTROLLER: + virDomainControllerDefFree(def->data.controller); + break; } VIR_FREE(def); @@ -561,6 +581,10 @@ void virDomainDefFree(virDomainDefPtr def) virDomainDiskDefFree(def->disks[i]); VIR_FREE(def->disks); + for (i = 0 ; i < def->ncontrollers ; i++) + virDomainControllerDefFree(def->controllers[i]); + VIR_FREE(def->controllers); + for (i = 0 ; i < def->nfss ; i++) virDomainFSDefFree(def->fss[i]); VIR_FREE(def->fss); @@ -1335,6 +1359,63 @@ cleanup: } +/* Parse the XML definition for a controller + * @param node XML nodeset to parse for controller definition + */ +static virDomainControllerDefPtr +virDomainControllerDefParseXML(virConnectPtr conn, + xmlNodePtr node, + int flags) +{ + virDomainControllerDefPtr def; + char *type = NULL; + char *idx = NULL; + + if (VIR_ALLOC(def) < 0) { + virReportOOMError(conn); + return NULL; + } + + type = virXMLPropString(node, "type"); + if (type) { + if ((def->type = virDomainDiskBusTypeFromString(type)) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("unknown disk controller type '%s'"), type); + goto error; + } + } + + idx = virXMLPropString(node, "index"); + if (idx) { + if (virStrToLong_i(idx, NULL, 10, &def->idx) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("cannot parse disk controller index %s"), idx); + goto error; + } + } + + if (virDomainDeviceInfoParseXML(conn, node, &def->info, flags) < 0) + goto error; + + if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Disk controllers must use the 'pci' address type")); + goto error; + } + +cleanup: + VIR_FREE(type); + VIR_FREE(idx); + + return def; + + error: + virDomainControllerDefFree(def); + def = NULL; + goto cleanup; +} + /* Parse the XML definition for a disk * @param node XML nodeset to parse for disk definition */ @@ -2995,6 +3076,10 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virConnectPtr conn, dev->type = VIR_DOMAIN_DEVICE_HOSTDEV; if (!(dev->data.hostdev = virDomainHostdevDefParseXML(conn, node, flags))) goto error; + } else if (xmlStrEqual(node->name, BAD_CAST "controller")) { + dev->type = VIR_DOMAIN_DEVICE_CONTROLLER; + if (!(dev->data.controller = virDomainControllerDefParseXML(conn, node, flags))) + goto error; } else { virDomainReportError(conn, VIR_ERR_XML_ERROR, "%s", _("unknown device type")); @@ -3067,6 +3152,59 @@ void virDomainDiskInsertPreAlloced(virDomainDefPtr def, } +int virDomainControllerInsert(virDomainDefPtr def, + virDomainControllerDefPtr controller) +{ + + if (VIR_REALLOC_N(def->controllers, def->ncontrollers+1) < 0) + return -1; + + virDomainControllerInsertPreAlloced(def, controller); + + return 0; +} + +void virDomainControllerInsertPreAlloced(virDomainDefPtr def, + virDomainControllerDefPtr controller) +{ + int i; + /* Tenatively plan to insert controller at the end. */ + int insertAt = -1; + + /* Then work backwards looking for controllers of + * the same type. If we find a controller with a + * index greater than the new one, insert at + * that position + */ + for (i = (def->ncontrollers - 1) ; i >= 0 ; i--) { + /* If bus matches and current controller is after + * new controller, then new controller should go here */ + if ((def->controllers[i]->type == controller->type) && + (def->controllers[i]->idx > controller->idx)) { + insertAt = i; + } else if (def->controllers[i]->type == controller->type && + insertAt == -1) { + /* Last controller with match bus is before the + * new controller, then put new controller just after + */ + insertAt = i + 1; + } + } + + /* No controllers with this bus yet, so put at end of list */ + if (insertAt == -1) + insertAt = def->ncontrollers; + + if (insertAt < def->ncontrollers) + memmove(def->controllers + insertAt + 1, + def->controllers + insertAt, + (sizeof(def->controllers[0]) * (def->ncontrollers-insertAt))); + + def->controllers[insertAt] = controller; + def->ncontrollers++; +} + + #ifndef PROXY static char *virDomainDefDefaultEmulator(virConnectPtr conn, virDomainDefPtr def, @@ -3382,6 +3520,25 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn, } VIR_FREE(nodes); + /* analysis of the controller devices */ + if ((n = virXPathNodeSet(conn, "./devices/controller", ctxt, &nodes)) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, + "%s", _("cannot extract controller devices")); + goto error; + } + if (n && VIR_ALLOC_N(def->controllers, n) < 0) + goto no_memory; + for (i = 0 ; i < n ; i++) { + virDomainControllerDefPtr controller = virDomainControllerDefParseXML(conn, + nodes[i], + flags); + if (!controller) + goto error; + + def->controllers[def->ncontrollers++] = controller; + } + VIR_FREE(nodes); + /* analysis of the filesystems */ if ((n = virXPathNodeSet(conn, "./devices/filesystem", ctxt, &nodes)) < 0) { virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, @@ -4299,6 +4456,35 @@ virDomainDiskDefFormat(virConnectPtr conn, } static int +virDomainControllerDefFormat(virConnectPtr conn, + virBufferPtr buf, + virDomainControllerDefPtr def) +{ + const char *type = virDomainControllerTypeToString(def->type); + + if (!type) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("unexpected controller type %d"), def->type); + return -1; + } + + virBufferVSprintf(buf, + " <controller type='%s' index='%d'", + type, def->idx); + + if (virDomainDeviceInfoIsSet(&def->info)) { + virBufferAddLit(buf, ">\n"); + if (virDomainDeviceInfoFormat(buf, &def->info) < 0) + return -1; + virBufferAddLit(buf, " </controller>\n"); + } else { + virBufferAddLit(buf, "/>\n"); + } + + return 0; +} + +static int virDomainFSDefFormat(virConnectPtr conn, virBufferPtr buf, virDomainFSDefPtr def) @@ -5045,6 +5231,10 @@ char *virDomainDefFormat(virConnectPtr conn, if (virDomainDiskDefFormat(conn, &buf, def->disks[n]) < 0) goto cleanup; + for (n = 0 ; n < def->ncontrollers ; n++) + if (virDomainControllerDefFormat(conn, &buf, def->controllers[n]) < 0) + goto cleanup; + for (n = 0 ; n < def->nfss ; n++) if (virDomainFSDefFormat(conn, &buf, def->fss[n]) < 0) goto cleanup; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a05835a..9f2271c 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -160,6 +160,25 @@ struct _virDomainDiskDef { }; +enum virDomainControllerType { + VIR_DOMAIN_CONTROLLER_TYPE_IDE, + VIR_DOMAIN_CONTROLLER_TYPE_FDC, + VIR_DOMAIN_CONTROLLER_TYPE_SCSI, + VIR_DOMAIN_CONTROLLER_TYPE_SATA, + + VIR_DOMAIN_CONTROLLER_TYPE_LAST +}; + +/* Stores the virtual disk controller configuration */ +typedef struct _virDomainControllerDef virDomainControllerDef; +typedef virDomainControllerDef *virDomainControllerDefPtr; +struct _virDomainControllerDef { + int type; + int idx; + virDomainDeviceInfo info; +}; + + /* Two types of disk backends */ enum virDomainFSType { VIR_DOMAIN_FS_TYPE_MOUNT, /* Better named 'bind' */ @@ -488,6 +507,7 @@ enum virDomainDeviceType { VIR_DOMAIN_DEVICE_VIDEO, VIR_DOMAIN_DEVICE_HOSTDEV, VIR_DOMAIN_DEVICE_WATCHDOG, + VIR_DOMAIN_DEVICE_CONTROLLER, VIR_DOMAIN_DEVICE_LAST, }; @@ -498,6 +518,7 @@ struct _virDomainDeviceDef { int type; union { virDomainDiskDefPtr disk; + virDomainControllerDefPtr controller; virDomainFSDefPtr fs; virDomainNetDefPtr net; virDomainInputDefPtr input; @@ -610,6 +631,9 @@ struct _virDomainDef { int ndisks; virDomainDiskDefPtr *disks; + int ncontrollers; + virDomainControllerDefPtr *controllers; + int nfss; virDomainFSDefPtr *fss; @@ -693,6 +717,7 @@ virDomainObjPtr virDomainFindByName(const virDomainObjListPtr doms, void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def); void virDomainInputDefFree(virDomainInputDefPtr def); void virDomainDiskDefFree(virDomainDiskDefPtr def); +void virDomainControllerDefFree(virDomainControllerDefPtr def); void virDomainFSDefFree(virDomainFSDefPtr def); void virDomainNetDefFree(virDomainNetDefPtr def); void virDomainChrDefFree(virDomainChrDefPtr def); @@ -775,6 +800,11 @@ void virDomainDiskInsertPreAlloced(virDomainDefPtr def, virDomainDiskDefPtr disk); void virDomainDiskDefAssignAddress(virDomainDiskDefPtr def); +int virDomainControllerInsert(virDomainDefPtr def, + virDomainControllerDefPtr controller); +void virDomainControllerInsertPreAlloced(virDomainDefPtr def, + virDomainControllerDefPtr controller); + int virDomainSaveXML(virConnectPtr conn, const char *configDir, virDomainDefPtr def, @@ -855,6 +885,7 @@ VIR_ENUM_DECL(virDomainDisk) VIR_ENUM_DECL(virDomainDiskDevice) VIR_ENUM_DECL(virDomainDiskBus) VIR_ENUM_DECL(virDomainDiskCache) +VIR_ENUM_DECL(virDomainController) VIR_ENUM_DECL(virDomainFS) VIR_ENUM_DECL(virDomainNet) VIR_ENUM_DECL(virDomainChrTarget) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 9a4f444..a346aa5 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -130,6 +130,8 @@ virDomainDiskDeviceTypeToString; virDomainDiskInsert; virDomainDiskInsertPreAlloced; virDomainDiskDefAssignAddress; +virDomainControllerInsert; +virDomainControllerInsertPreAlloced; virDomainFindByID; virDomainFindByName; virDomainFindByUUID; -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:02PM +0000, Daniel P. Berrange wrote:
From: Wolfgang Mauerer <wolfgang.mauerer@siemens.com>
This augments virDomainDevice with a <controller> element that is used to represent disk controllers (e.g., scsi controllers). The XML format is given by
<controller type="scsi" index="<num>"> <address type="pci" domain="0xNUM" bus="0xNUM" slot="0xNUM"/> </controller>
Actually we also allow decimal or even octal values
where type denotes the disk interface (scsi, ide,...), index is an integer that identifies the controller for association with disks, and the <address> element specifies the controller address on the PCI bus as described in previous commits The address element can be omitted; in this case, an address will be assigned automatically.
Most of the code in this patch is from Wolfgang Mauerer's previous disk controller series
* docs/schemas/domain.rng: Define syntax for <controller> XML element * src/conf/domain_conf.c, src/conf/domain_conf.h: Define virDomainControllerDef struct, and routines for parsing and formatting XML * src/libvirt_private.syms: Add virDomainControllerInsert and virDomainControllerDefFree [...] +void virDomainControllerDefFree(virDomainControllerDefPtr def) +{ + if (!def) + return; + + virDomainDeviceInfoClear(&def->info);
superfluous, unless we start allocating data there.
+ VIR_FREE(def); +} + [...]
+/* Parse the XML definition for a controller + * @param node XML nodeset to parse for controller definition + */ +static virDomainControllerDefPtr +virDomainControllerDefParseXML(virConnectPtr conn, + xmlNodePtr node, + int flags) +{ + virDomainControllerDefPtr def; + char *type = NULL; + char *idx = NULL; + + if (VIR_ALLOC(def) < 0) { + virReportOOMError(conn); + return NULL; + } + + type = virXMLPropString(node, "type"); + if (type) { + if ((def->type = virDomainDiskBusTypeFromString(type)) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("unknown disk controller type '%s'"), type); + goto error; + } + } + + idx = virXMLPropString(node, "index");
I like the code style found in the previous parsing routines where all the virXMLPropString are done at the beginning and we can drop the NULL initializations, looks simpler to me, but it's really not a big deal.
+void virDomainControllerInsertPreAlloced(virDomainDefPtr def, + virDomainControllerDefPtr controller) +{ + int i; + /* Tenatively plan to insert controller at the end. */ + int insertAt = -1; + + /* Then work backwards looking for controllers of + * the same type. If we find a controller with a + * index greater than the new one, insert at + * that position + */ + for (i = (def->ncontrollers - 1) ; i >= 0 ; i--) { + /* If bus matches and current controller is after + * new controller, then new controller should go here */ + if ((def->controllers[i]->type == controller->type) && + (def->controllers[i]->idx > controller->idx)) { + insertAt = i; + } else if (def->controllers[i]->type == controller->type && + insertAt == -1) { + /* Last controller with match bus is before the + * new controller, then put new controller just after + */ + insertAt = i + 1; + } + } + + /* No controllers with this bus yet, so put at end of list */ + if (insertAt == -1) + insertAt = def->ncontrollers; + + if (insertAt < def->ncontrollers) + memmove(def->controllers + insertAt + 1, + def->controllers + insertAt, + (sizeof(def->controllers[0]) * (def->ncontrollers-insertAt))); + + def->controllers[insertAt] = controller; + def->ncontrollers++; +}
I find that a bit complex, instead of trying to insert in an ordered fashion, what about another routine sorting the full set in one pass after the array had been fully initialized. We could use qsort and a single comparison function. I think that would be equivalent, except controllers would be ordered by type too and we would loose that order if provided by the user. Unsure if this is a significant information. Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Fri, Jan 15, 2010 at 02:08:54PM +0100, Daniel Veillard wrote:
On Fri, Jan 08, 2010 at 05:23:02PM +0000, Daniel P. Berrange wrote:
From: Wolfgang Mauerer <wolfgang.mauerer@siemens.com>
This augments virDomainDevice with a <controller> element that is used to represent disk controllers (e.g., scsi controllers). The XML format is given by
<controller type="scsi" index="<num>"> <address type="pci" domain="0xNUM" bus="0xNUM" slot="0xNUM"/> </controller>
Actually we also allow decimal or even octal values
where type denotes the disk interface (scsi, ide,...), index is an integer that identifies the controller for association with disks, and the <address> element specifies the controller address on the PCI bus as described in previous commits The address element can be omitted; in this case, an address will be assigned automatically.
Most of the code in this patch is from Wolfgang Mauerer's previous disk controller series
* docs/schemas/domain.rng: Define syntax for <controller> XML element * src/conf/domain_conf.c, src/conf/domain_conf.h: Define virDomainControllerDef struct, and routines for parsing and formatting XML * src/libvirt_private.syms: Add virDomainControllerInsert and virDomainControllerDefFree [...] +void virDomainControllerDefFree(virDomainControllerDefPtr def) +{ + if (!def) + return; + + virDomainDeviceInfoClear(&def->info);
superfluous, unless we start allocating data there.
+ VIR_FREE(def); +} + [...]
+/* Parse the XML definition for a controller + * @param node XML nodeset to parse for controller definition + */ +static virDomainControllerDefPtr +virDomainControllerDefParseXML(virConnectPtr conn, + xmlNodePtr node, + int flags) +{ + virDomainControllerDefPtr def; + char *type = NULL; + char *idx = NULL; + + if (VIR_ALLOC(def) < 0) { + virReportOOMError(conn); + return NULL; + } + + type = virXMLPropString(node, "type"); + if (type) { + if ((def->type = virDomainDiskBusTypeFromString(type)) < 0) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("unknown disk controller type '%s'"), type); + goto error; + } + } + + idx = virXMLPropString(node, "index");
I like the code style found in the previous parsing routines where all the virXMLPropString are done at the beginning and we can drop the NULL initializations, looks simpler to me, but it's really not a big deal.
+void virDomainControllerInsertPreAlloced(virDomainDefPtr def, + virDomainControllerDefPtr controller) +{ + int i; + /* Tenatively plan to insert controller at the end. */ + int insertAt = -1; + + /* Then work backwards looking for controllers of + * the same type. If we find a controller with a + * index greater than the new one, insert at + * that position + */ + for (i = (def->ncontrollers - 1) ; i >= 0 ; i--) { + /* If bus matches and current controller is after + * new controller, then new controller should go here */ + if ((def->controllers[i]->type == controller->type) && + (def->controllers[i]->idx > controller->idx)) { + insertAt = i; + } else if (def->controllers[i]->type == controller->type && + insertAt == -1) { + /* Last controller with match bus is before the + * new controller, then put new controller just after + */ + insertAt = i + 1; + } + } + + /* No controllers with this bus yet, so put at end of list */ + if (insertAt == -1) + insertAt = def->ncontrollers; + + if (insertAt < def->ncontrollers) + memmove(def->controllers + insertAt + 1, + def->controllers + insertAt, + (sizeof(def->controllers[0]) * (def->ncontrollers-insertAt))); + + def->controllers[insertAt] = controller; + def->ncontrollers++; +}
I find that a bit complex, instead of trying to insert in an ordered fashion, what about another routine sorting the full set in one pass after the array had been fully initialized. We could use qsort and a single comparison function. I think that would be equivalent, except controllers would be ordered by type too and we would loose that order if provided by the user. Unsure if this is a significant information.
Hum, I realize I forgot to ack it, that's more a question than anything else ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Convert the QEMU monitor APIs over to use virDomainDeviceAddress structs for passing addresses in/out, instead of individual bits. This makes the number of parameters smaller & easier to deal with. No functional change * src/qemu/qemu_driver.c, src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h, src/qemu/qemu_monitor_text.c, src/qemu/qemu_monitor_text.h: Change monitor hotplug APIs to take an explicit address ptr for all host/guest addresses --- src/qemu/qemu_driver.c | 35 +++++++++--------------- src/qemu/qemu_monitor.c | 60 ++++++++++++------------------------------ src/qemu/qemu_monitor.h | 21 +++----------- src/qemu/qemu_monitor_json.c | 55 +++++++++++++++++--------------------- src/qemu/qemu_monitor_json.h | 22 +++------------ src/qemu/qemu_monitor_text.c | 56 ++++++++++++++------------------------- src/qemu/qemu_monitor_text.h | 22 +++------------ 7 files changed, 90 insertions(+), 181 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 3588531..8c2e6d6 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -5080,6 +5080,7 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn, int i, ret; const char* type = virDomainDiskBusTypeToString(dev->data.disk->bus); qemuDomainObjPrivatePtr priv = vm->privateData; + virDomainDevicePCIAddress guestAddr; for (i = 0 ; i < vm->def->ndisks ; i++) { if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) { @@ -5098,13 +5099,12 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn, ret = qemuMonitorAddPCIDisk(priv->mon, dev->data.disk->src, type, - &dev->data.disk->info.addr.pci.domain, - &dev->data.disk->info.addr.pci.bus, - &dev->data.disk->info.addr.pci.slot); + &guestAddr); qemuDomainObjExitMonitorWithDriver(driver, vm); if (ret == 0) { dev->data.disk->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + memcpy(&dev->data.disk->info.addr.pci, &guestAddr, sizeof(guestAddr)); virDomainDiskInsertPreAlloced(vm->def, dev->data.disk); } @@ -5161,6 +5161,7 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn, char *nicstr = NULL; char *netstr = NULL; int ret = -1; + virDomainDevicePCIAddress guestAddr; if (!(qemuCmdFlags & QEMUD_CMD_FLAG_HOST_NET_ADD)) { qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT, "%s", @@ -5229,13 +5230,12 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn, qemuDomainObjEnterMonitorWithDriver(driver, vm); if (qemuMonitorAddPCINetwork(priv->mon, nicstr, - &net->info.addr.pci.domain, - &net->info.addr.pci.bus, - &net->info.addr.pci.slot) < 0) { + &guestAddr) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); goto try_remove; } net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + memcpy(&net->info.addr.pci, &guestAddr, sizeof(guestAddr)); qemuDomainObjExitMonitorWithDriver(driver, vm); ret = 0; @@ -5287,6 +5287,7 @@ static int qemudDomainAttachHostPciDevice(virConnectPtr conn, virDomainHostdevDefPtr hostdev = dev->data.hostdev; pciDevice *pci; int ret; + virDomainDevicePCIAddress guestAddr; if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0) { virReportOOMError(conn); @@ -5314,17 +5315,13 @@ static int qemudDomainAttachHostPciDevice(virConnectPtr conn, qemuDomainObjEnterMonitorWithDriver(driver, vm); ret = qemuMonitorAddPCIHostDevice(priv->mon, - hostdev->source.subsys.u.pci.domain, - hostdev->source.subsys.u.pci.bus, - hostdev->source.subsys.u.pci.slot, - hostdev->source.subsys.u.pci.function, - &hostdev->info.addr.pci.domain, - &hostdev->info.addr.pci.bus, - &hostdev->info.addr.pci.slot); + &hostdev->source.subsys.u.pci, + &guestAddr); qemuDomainObjExitMonitorWithDriver(driver, vm); if (ret < 0) goto error; hostdev->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + memcpy(&hostdev->info.addr.pci, &guestAddr, sizeof(guestAddr)); vm->def->hostdevs[vm->def->nhostdevs++] = hostdev; @@ -5563,9 +5560,7 @@ static int qemudDomainDetachPciDiskDevice(virConnectPtr conn, qemuDomainObjEnterMonitorWithDriver(driver, vm); if (qemuMonitorRemovePCIDevice(priv->mon, - detach->info.addr.pci.domain, - detach->info.addr.pci.bus, - detach->info.addr.pci.slot) < 0) { + &detach->info.addr.pci) < 0) { qemuDomainObjExitMonitor(vm); goto cleanup; } @@ -5635,9 +5630,7 @@ qemudDomainDetachNetDevice(virConnectPtr conn, qemuDomainObjEnterMonitorWithDriver(driver, vm); if (qemuMonitorRemovePCIDevice(priv->mon, - detach->info.addr.pci.domain, - detach->info.addr.pci.bus, - detach->info.addr.pci.slot) < 0) { + &detach->info.addr.pci) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); goto cleanup; } @@ -5724,9 +5717,7 @@ static int qemudDomainDetachHostPciDevice(virConnectPtr conn, qemuDomainObjEnterMonitorWithDriver(driver, vm); if (qemuMonitorRemovePCIDevice(priv->mon, - detach->info.addr.pci.domain, - detach->info.addr.pci.bus, - detach->info.addr.pci.slot) < 0) { + &detach->info.addr.pci) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); return -1; } diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 750e3e6..caf2d35 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1117,33 +1117,18 @@ int qemuMonitorAddUSBDeviceMatch(qemuMonitorPtr mon, int qemuMonitorAddPCIHostDevice(qemuMonitorPtr mon, - unsigned hostDomain, - unsigned hostBus, - unsigned hostSlot, - unsigned hostFunction, - unsigned *guestDomain, - unsigned *guestBus, - unsigned *guestSlot) + virDomainDevicePCIAddress *hostAddr, + virDomainDevicePCIAddress *guestAddr) { int ret; DEBUG("mon=%p, fd=%d domain=%d bus=%d slot=%d function=%d", mon, mon->fd, - hostDomain, hostBus, hostSlot, hostFunction); + hostAddr->domain, hostAddr->bus, hostAddr->slot, hostAddr->function); if (mon->json) - ret = qemuMonitorJSONAddPCIHostDevice(mon, hostDomain, - hostBus, hostSlot, - hostFunction, - guestDomain, - guestBus, - guestSlot); + ret = qemuMonitorJSONAddPCIHostDevice(mon, hostAddr, guestAddr); else - ret = qemuMonitorTextAddPCIHostDevice(mon, hostDomain, - hostBus, hostSlot, - hostFunction, - guestDomain, - guestBus, - guestSlot); + ret = qemuMonitorTextAddPCIHostDevice(mon, hostAddr, guestAddr); return ret; } @@ -1151,58 +1136,47 @@ int qemuMonitorAddPCIHostDevice(qemuMonitorPtr mon, int qemuMonitorAddPCIDisk(qemuMonitorPtr mon, const char *path, const char *bus, - unsigned *guestDomain, - unsigned *guestBus, - unsigned *guestSlot) + virDomainDevicePCIAddress *guestAddr) { int ret; DEBUG("mon=%p, fd=%d path=%s bus=%s", mon, mon->fd, path, bus); if (mon->json) - ret = qemuMonitorJSONAddPCIDisk(mon, path, bus, - guestDomain, guestBus, guestSlot); + ret = qemuMonitorJSONAddPCIDisk(mon, path, bus, guestAddr); else - ret = qemuMonitorTextAddPCIDisk(mon, path, bus, - guestDomain, guestBus, guestSlot); + ret = qemuMonitorTextAddPCIDisk(mon, path, bus, guestAddr); return ret; } int qemuMonitorAddPCINetwork(qemuMonitorPtr mon, const char *nicstr, - unsigned *guestDomain, - unsigned *guestBus, - unsigned *guestSlot) + virDomainDevicePCIAddress *guestAddr) { int ret; DEBUG("mon=%p, fd=%d nicstr=%s", mon, mon->fd, nicstr); if (mon->json) - ret = qemuMonitorJSONAddPCINetwork(mon, nicstr, guestDomain, - guestBus, guestSlot); + ret = qemuMonitorJSONAddPCINetwork(mon, nicstr, guestAddr); else - ret = qemuMonitorTextAddPCINetwork(mon, nicstr, guestDomain, - guestBus, guestSlot); + ret = qemuMonitorTextAddPCINetwork(mon, nicstr, guestAddr); return ret; } int qemuMonitorRemovePCIDevice(qemuMonitorPtr mon, - unsigned guestDomain, - unsigned guestBus, - unsigned guestSlot) + virDomainDevicePCIAddress *guestAddr) { int ret; - DEBUG("mon=%p, fd=%d domain=%d bus=%d slot=%d", - mon, mon->fd, guestDomain, guestBus, guestSlot); + DEBUG("mon=%p, fd=%d domain=%d bus=%d slot=%d function=%d", + mon, mon->fd, guestAddr->domain, guestAddr->bus, + guestAddr->slot, guestAddr->function); if (mon->json) - ret = qemuMonitorJSONRemovePCIDevice(mon, guestDomain, - guestBus, guestSlot); + ret = qemuMonitorJSONRemovePCIDevice(mon, guestAddr); else - ret = qemuMonitorTextRemovePCIDevice(mon, guestDomain, - guestBus, guestSlot); + ret = qemuMonitorTextRemovePCIDevice(mon, guestAddr); return ret; } diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index db00b26..e0a0552 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -222,13 +222,8 @@ int qemuMonitorAddUSBDeviceMatch(qemuMonitorPtr mon, int qemuMonitorAddPCIHostDevice(qemuMonitorPtr mon, - unsigned hostDomain, - unsigned hostBus, - unsigned hostSlot, - unsigned hostFunction, - unsigned *guestDomain, - unsigned *guestBus, - unsigned *guestSlot); + virDomainDevicePCIAddress *hostAddr, + virDomainDevicePCIAddress *guestAddr); /* XXX disk driver type eg, qcow/etc. * XXX cache mode @@ -236,23 +231,17 @@ int qemuMonitorAddPCIHostDevice(qemuMonitorPtr mon, int qemuMonitorAddPCIDisk(qemuMonitorPtr mon, const char *path, const char *bus, - unsigned *guestDomain, - unsigned *guestBus, - unsigned *guestSlot); + virDomainDevicePCIAddress *guestAddr); /* XXX do we really want to hardcode 'nicstr' as the * sendable item here */ int qemuMonitorAddPCINetwork(qemuMonitorPtr mon, const char *nicstr, - unsigned *guestDomain, - unsigned *guestBus, - unsigned *guestSlot); + virDomainDevicePCIAddress *guestAddr); int qemuMonitorRemovePCIDevice(qemuMonitorPtr mon, - unsigned guestDomain, - unsigned guestBus, - unsigned guestSlot); + virDomainDevicePCIAddress *guestAddr); int qemuMonitorSendFileHandle(qemuMonitorPtr mon, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index b96f4ac..e0a3225 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -1206,9 +1206,7 @@ int qemuMonitorJSONAddUSBDeviceMatch(qemuMonitorPtr mon, /* XXX qemu also returns a 'function' number now */ static int qemuMonitorJSONGetGuestAddress(virJSONValuePtr reply, - unsigned *guestDomain, - unsigned *guestBus, - unsigned *guestSlot) + virDomainDevicePCIAddress *guestAddr) { virJSONValuePtr addr; @@ -1219,47 +1217,48 @@ qemuMonitorJSONGetGuestAddress(virJSONValuePtr reply, return -1; } - if (virJSONValueObjectGetNumberUint(addr, "domain", guestDomain) < 0) { + if (virJSONValueObjectGetNumberUint(addr, "domain", &guestAddr->domain) < 0) { qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("pci_add reply was missing device domain number")); return -1; } - if (virJSONValueObjectGetNumberUint(addr, "bus", guestBus) < 0) { + if (virJSONValueObjectGetNumberUint(addr, "bus", &guestAddr->bus) < 0) { qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("pci_add reply was missing device bus number")); return -1; } - if (virJSONValueObjectGetNumberUint(addr, "slot", guestSlot) < 0) { + if (virJSONValueObjectGetNumberUint(addr, "slot", &guestAddr->slot) < 0) { qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s", _("pci_add reply was missing device slot number")); return -1; } + if (virJSONValueObjectGetNumberUint(addr, "function", &guestAddr->function) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("pci_add reply was missing device function number")); + return -1; + } + return 0; } int qemuMonitorJSONAddPCIHostDevice(qemuMonitorPtr mon, - unsigned hostDomain ATTRIBUTE_UNUSED, - unsigned hostBus, - unsigned hostSlot, - unsigned hostFunction, - unsigned *guestDomain, - unsigned *guestBus, - unsigned *guestSlot) + virDomainDevicePCIAddress *hostAddr, + virDomainDevicePCIAddress *guestAddr) { int ret; virJSONValuePtr cmd; virJSONValuePtr reply = NULL; char *dev; - *guestDomain = *guestBus = *guestSlot = 0; + memset(guestAddr, 0, sizeof(*guestAddr)); /* XXX hostDomain */ if (virAsprintf(&dev, "host=%.2x:%.2x.%.1x", - hostBus, hostSlot, hostFunction) < 0) { + hostAddr->bus, hostAddr->slot, hostAddr->function) < 0) { virReportOOMError(NULL); return -1; } @@ -1279,7 +1278,7 @@ int qemuMonitorJSONAddPCIHostDevice(qemuMonitorPtr mon, ret = qemuMonitorJSONCheckError(cmd, reply); if (ret == 0 && - qemuMonitorJSONGetGuestAddress(reply, guestDomain, guestBus, guestSlot) < 0) + qemuMonitorJSONGetGuestAddress(reply, guestAddr) < 0) ret = -1; virJSONValueFree(cmd); @@ -1291,15 +1290,14 @@ int qemuMonitorJSONAddPCIHostDevice(qemuMonitorPtr mon, int qemuMonitorJSONAddPCIDisk(qemuMonitorPtr mon, const char *path, const char *bus, - unsigned *guestDomain, - unsigned *guestBus, - unsigned *guestSlot) { + virDomainDevicePCIAddress *guestAddr) +{ int ret; virJSONValuePtr cmd; virJSONValuePtr reply = NULL; char *dev; - *guestDomain = *guestBus = *guestSlot = 0; + memset(guestAddr, 0, sizeof(*guestAddr)); if (virAsprintf(&dev, "file=%s,if=%s", path, bus) < 0) { virReportOOMError(NULL); @@ -1321,7 +1319,7 @@ int qemuMonitorJSONAddPCIDisk(qemuMonitorPtr mon, ret = qemuMonitorJSONCheckError(cmd, reply); if (ret == 0 && - qemuMonitorJSONGetGuestAddress(reply, guestDomain, guestBus, guestSlot) < 0) + qemuMonitorJSONGetGuestAddress(reply, guestAddr) < 0) ret = -1; virJSONValueFree(cmd); @@ -1332,9 +1330,7 @@ int qemuMonitorJSONAddPCIDisk(qemuMonitorPtr mon, int qemuMonitorJSONAddPCINetwork(qemuMonitorPtr mon, const char *nicstr, - unsigned *guestDomain, - unsigned *guestBus, - unsigned *guestSlot) + virDomainDevicePCIAddress *guestAddr) { int ret; virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("pci_add", @@ -1344,7 +1340,7 @@ int qemuMonitorJSONAddPCINetwork(qemuMonitorPtr mon, NULL); virJSONValuePtr reply = NULL; - *guestDomain = *guestBus = *guestSlot = 0; + memset(guestAddr, 0, sizeof(*guestAddr)); if (!cmd) return -1; @@ -1355,7 +1351,7 @@ int qemuMonitorJSONAddPCINetwork(qemuMonitorPtr mon, ret = qemuMonitorJSONCheckError(cmd, reply); if (ret == 0 && - qemuMonitorJSONGetGuestAddress(reply, guestDomain, guestBus, guestSlot) < 0) + qemuMonitorJSONGetGuestAddress(reply, guestAddr) < 0) ret = -1; virJSONValueFree(cmd); @@ -1365,17 +1361,16 @@ int qemuMonitorJSONAddPCINetwork(qemuMonitorPtr mon, int qemuMonitorJSONRemovePCIDevice(qemuMonitorPtr mon, - unsigned guestDomain, - unsigned guestBus, - unsigned guestSlot) + virDomainDevicePCIAddress *guestAddr) { int ret; virJSONValuePtr cmd; virJSONValuePtr reply = NULL; char *addr; + /* XXX what about function ? */ if (virAsprintf(&addr, "%.4x:%.2x:%.2x", - guestDomain, guestBus, guestSlot) < 0) { + guestAddr->domain, guestAddr->bus, guestAddr->slot) < 0) { virReportOOMError(NULL); return -1; } diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 62a88c0..74d88b2 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -112,32 +112,20 @@ int qemuMonitorJSONAddUSBDeviceMatch(qemuMonitorPtr mon, int qemuMonitorJSONAddPCIHostDevice(qemuMonitorPtr mon, - unsigned hostDomain, - unsigned hostBus, - unsigned hostSlot, - unsigned hostFunction, - unsigned *guestDomain, - unsigned *guestBus, - unsigned *guestSlot); + virDomainDevicePCIAddress *hostAddr, + virDomainDevicePCIAddress *guestAddr); int qemuMonitorJSONAddPCIDisk(qemuMonitorPtr mon, const char *path, const char *bus, - unsigned *guestDomain, - unsigned *guestBus, - unsigned *guestSlot); + virDomainDevicePCIAddress *guestAddr); int qemuMonitorJSONAddPCINetwork(qemuMonitorPtr mon, const char *nicstr, - unsigned *guestDomain, - unsigned *guestBus, - unsigned *guestSlot); + virDomainDevicePCIAddress *guestAddr); int qemuMonitorJSONRemovePCIDevice(qemuMonitorPtr mon, - unsigned guestDomain, - unsigned guestBus, - unsigned guestSlot); - + virDomainDevicePCIAddress *guestAddr); int qemuMonitorJSONSendFileHandle(qemuMonitorPtr mon, const char *fdname, diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index 5b9ced2..7c8b0a2 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -1281,9 +1281,7 @@ int qemuMonitorTextAddUSBDeviceMatch(qemuMonitorPtr mon, static int qemuMonitorTextParsePciAddReply(qemuMonitorPtr mon ATTRIBUTE_UNUSED, const char *reply, - unsigned *domain, - unsigned *bus, - unsigned *slot) + virDomainDevicePCIAddress *addr) { char *s, *e; @@ -1300,7 +1298,7 @@ qemuMonitorTextParsePciAddReply(qemuMonitorPtr mon ATTRIBUTE_UNUSED, if (STRPREFIX(s, "domain ")) { s += strlen("domain "); - if (virStrToLong_ui(s, &e, 10, domain) == -1) { + if (virStrToLong_ui(s, &e, 10, &addr->domain) == -1) { VIR_WARN(_("Unable to parse domain number '%s'\n"), s); return -1; } @@ -1318,7 +1316,7 @@ qemuMonitorTextParsePciAddReply(qemuMonitorPtr mon ATTRIBUTE_UNUSED, } s += strlen("bus "); - if (virStrToLong_ui(s, &e, 10, bus) == -1) { + if (virStrToLong_ui(s, &e, 10, &addr->bus) == -1) { VIR_WARN(_("Unable to parse bus number '%s'\n"), s); return -1; } @@ -1335,7 +1333,7 @@ qemuMonitorTextParsePciAddReply(qemuMonitorPtr mon ATTRIBUTE_UNUSED, } s += strlen("slot "); - if (virStrToLong_ui(s, &e, 10, slot) == -1) { + if (virStrToLong_ui(s, &e, 10, &addr->slot) == -1) { VIR_WARN(_("Unable to parse slot number '%s'\n"), s); return -1; } @@ -1345,23 +1343,18 @@ qemuMonitorTextParsePciAddReply(qemuMonitorPtr mon ATTRIBUTE_UNUSED, int qemuMonitorTextAddPCIHostDevice(qemuMonitorPtr mon, - unsigned hostDomain ATTRIBUTE_UNUSED, - unsigned hostBus, - unsigned hostSlot, - unsigned hostFunction, - unsigned *guestDomain, - unsigned *guestBus, - unsigned *guestSlot) + virDomainDevicePCIAddress *hostAddr, + virDomainDevicePCIAddress *guestAddr) { char *cmd; char *reply = NULL; int ret = -1; - *guestDomain = *guestBus = *guestSlot = 0; + memset(guestAddr, 0, sizeof(*guestAddr)); - /* XXX hostDomain */ + /* XXX hostAddr->domain */ if (virAsprintf(&cmd, "pci_add pci_addr=auto host host=%.2x:%.2x.%.1x", - hostBus, hostSlot, hostFunction) < 0) { + hostAddr->bus, hostAddr->slot, hostAddr->function) < 0) { virReportOOMError(NULL); goto cleanup; } @@ -1378,10 +1371,7 @@ int qemuMonitorTextAddPCIHostDevice(qemuMonitorPtr mon, goto cleanup; } - if (qemuMonitorTextParsePciAddReply(mon, reply, - guestDomain, - guestBus, - guestSlot) < 0) { + if (qemuMonitorTextParsePciAddReply(mon, reply, guestAddr) < 0) { qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, _("parsing pci_add reply failed: %s"), reply); goto cleanup; @@ -1399,9 +1389,8 @@ cleanup: int qemuMonitorTextAddPCIDisk(qemuMonitorPtr mon, const char *path, const char *bus, - unsigned *guestDomain, - unsigned *guestBus, - unsigned *guestSlot) { + virDomainDevicePCIAddress *guestAddr) +{ char *cmd = NULL; char *reply = NULL; char *safe_path = NULL; @@ -1427,8 +1416,7 @@ try_command: goto cleanup; } - if (qemuMonitorTextParsePciAddReply(mon, reply, - guestDomain, guestBus, guestSlot) < 0) { + if (qemuMonitorTextParsePciAddReply(mon, reply, guestAddr) < 0) { if (!tryOldSyntax && strstr(reply, "invalid char in expression")) { VIR_FREE(reply); VIR_FREE(cmd); @@ -1453,9 +1441,7 @@ cleanup: int qemuMonitorTextAddPCINetwork(qemuMonitorPtr mon, const char *nicstr, - unsigned *guestDomain, - unsigned *guestBus, - unsigned *guestSlot) + virDomainDevicePCIAddress *guestAddr) { char *cmd; char *reply = NULL; @@ -1472,8 +1458,7 @@ int qemuMonitorTextAddPCINetwork(qemuMonitorPtr mon, goto cleanup; } - if (qemuMonitorTextParsePciAddReply(mon, reply, - guestDomain, guestBus, guestSlot) < 0) { + if (qemuMonitorTextParsePciAddReply(mon, reply, guestAddr) < 0) { qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, _("parsing pci_add reply failed: %s"), reply); goto cleanup; @@ -1489,9 +1474,7 @@ cleanup: int qemuMonitorTextRemovePCIDevice(qemuMonitorPtr mon, - unsigned guestDomain, - unsigned guestBus, - unsigned guestSlot) + virDomainDevicePCIAddress *guestAddr) { char *cmd = NULL; char *reply = NULL; @@ -1500,13 +1483,14 @@ int qemuMonitorTextRemovePCIDevice(qemuMonitorPtr mon, try_command: if (tryOldSyntax) { - if (virAsprintf(&cmd, "pci_del 0 %.2x", guestSlot) < 0) { + if (virAsprintf(&cmd, "pci_del 0 %.2x", guestAddr->slot) < 0) { virReportOOMError(NULL); goto cleanup; } } else { + /* XXX function ? */ if (virAsprintf(&cmd, "pci_del pci_addr=%.4x:%.2x:%.2x", - guestDomain, guestBus, guestSlot) < 0) { + guestAddr->domain, guestAddr->bus, guestAddr->slot) < 0) { virReportOOMError(NULL); goto cleanup; } @@ -1534,7 +1518,7 @@ try_command: strstr(reply, "Invalid pci address")) { qemudReportError (NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, _("failed to detach PCI device, invalid address %.4x:%.2x:%.2x: %s"), - guestDomain, guestBus, guestSlot, reply); + guestAddr->domain, guestAddr->bus, guestAddr->slot, reply); goto cleanup; } diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h index 5897a03..f1f2f77 100644 --- a/src/qemu/qemu_monitor_text.h +++ b/src/qemu/qemu_monitor_text.h @@ -116,32 +116,20 @@ int qemuMonitorTextAddUSBDeviceMatch(qemuMonitorPtr mon, int qemuMonitorTextAddPCIHostDevice(qemuMonitorPtr mon, - unsigned hostDomain, - unsigned hostBus, - unsigned hostSlot, - unsigned hostFunction, - unsigned *guestDomain, - unsigned *guestBus, - unsigned *guestSlot); + virDomainDevicePCIAddress *hostAddr, + virDomainDevicePCIAddress *guestAddr); int qemuMonitorTextAddPCIDisk(qemuMonitorPtr mon, const char *path, const char *bus, - unsigned *guestDomain, - unsigned *guestBus, - unsigned *guestSlot); + virDomainDevicePCIAddress *guestAddr); int qemuMonitorTextAddPCINetwork(qemuMonitorPtr mon, const char *nicstr, - unsigned *guestDomain, - unsigned *guestBus, - unsigned *guestSlot); + virDomainDevicePCIAddress *guestAddr); int qemuMonitorTextRemovePCIDevice(qemuMonitorPtr mon, - unsigned guestDomain, - unsigned guestBus, - unsigned guestSlot); - + virDomainDevicePCIAddress *guestAddr); int qemuMonitorTextSendFileHandle(qemuMonitorPtr mon, const char *fdname, -- 1.6.5.2

On 01/08/2010 06:23 PM, Daniel P. Berrange wrote:
@@ -1206,9 +1206,7 @@ int qemuMonitorJSONAddUSBDeviceMatch(qemuMonitorPtr mon, /* XXX qemu also returns a 'function' number now */
Wrong comment now. Paolo

On Fri, Jan 08, 2010 at 05:23:03PM +0000, Daniel P. Berrange wrote:
Convert the QEMU monitor APIs over to use virDomainDeviceAddress structs for passing addresses in/out, instead of individual bits. This makes the number of parameters smaller & easier to deal with. No functional change
* src/qemu/qemu_driver.c, src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h, src/qemu/qemu_monitor_text.c, src/qemu/qemu_monitor_text.h: Change monitor hotplug APIs to take an explicit address ptr for all host/guest addresses --- src/qemu/qemu_driver.c | 35 +++++++++--------------- src/qemu/qemu_monitor.c | 60 ++++++++++++------------------------------ src/qemu/qemu_monitor.h | 21 +++----------- src/qemu/qemu_monitor_json.c | 55 +++++++++++++++++--------------------- src/qemu/qemu_monitor_json.h | 22 +++------------ src/qemu/qemu_monitor_text.c | 56 ++++++++++++++------------------------- src/qemu/qemu_monitor_text.h | 22 +++------------ 7 files changed, 90 insertions(+), 181 deletions(-)
ACK, makes the code way nicer ! Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

To enable it to be called from multiple locations, split out the code for building the -drive arg string. This will be needed by later patches which do drive hotplug, the conversion to use -device, and the conversion to controller/bus/unit addressing * src/qemu/qemu_conf.c, src/qemu/qemu_conf.h: Add qemuBuildDriveStr for building -drive arg string --- src/qemu/qemu_conf.c | 191 ++++++++++++++++++++++++++----------------------- src/qemu/qemu_conf.h | 5 ++ 2 files changed, 106 insertions(+), 90 deletions(-) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index c575d63..94f4cc0 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1523,6 +1523,104 @@ qemuAssignNetNames(virDomainDefPtr def, return 0; } +#define QEMU_SERIAL_PARAM_ACCEPTED_CHARS \ + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_" + +static int +qemuSafeSerialParamValue(virConnectPtr conn, + const char *value) +{ + if (strspn(value, QEMU_SERIAL_PARAM_ACCEPTED_CHARS) != strlen (value)) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("driver serial '%s' contains unsafe characters"), + value); + return -1; + } + + return 0; +} + + +char * +qemuBuildDriveStr(virDomainDiskDefPtr disk, + int bootable, + int qemuCmdFlags) +{ + virBuffer opt = VIR_BUFFER_INITIALIZER; + const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus); + int idx = virDiskNameToIndex(disk->dst); + + if (idx < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("unsupported disk type '%s'"), disk->dst); + goto error; + } + + if (disk->src) { + if (disk->type == VIR_DOMAIN_DISK_TYPE_DIR) { + /* QEMU only supports magic FAT format for now */ + if (disk->driverType && + STRNEQ(disk->driverType, "fat")) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("unsupported disk driver type for '%s'"), + disk->driverType); + goto error; + } + if (!disk->readonly) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s", + _("cannot create virtual FAT disks in read-write mode")); + goto error; + } + if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) + virBufferVSprintf(&opt, "file=fat:floppy:%s,", disk->src); + else + virBufferVSprintf(&opt, "file=fat:%s,", disk->src); + } else { + virBufferVSprintf(&opt, "file=%s,", disk->src); + } + } + virBufferVSprintf(&opt, "if=%s", bus); + if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) + virBufferAddLit(&opt, ",media=cdrom"); + virBufferVSprintf(&opt, ",index=%d", idx); + if (bootable && + disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) + virBufferAddLit(&opt, ",boot=on"); + if (disk->driverType && + disk->type != VIR_DOMAIN_DISK_TYPE_DIR && + qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_FORMAT) + virBufferVSprintf(&opt, ",format=%s", disk->driverType); + if (disk->serial && + (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_SERIAL)) { + if (qemuSafeSerialParamValue(NULL, disk->serial) < 0) + goto error; + virBufferVSprintf(&opt, ",serial=%s", disk->serial); + } + + if (disk->cachemode) { + const char *mode = + (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_CACHE_V2) ? + qemuDiskCacheV2TypeToString(disk->cachemode) : + qemuDiskCacheV1TypeToString(disk->cachemode); + + virBufferVSprintf(&opt, ",cache=%s", mode); + } else if (disk->shared && !disk->readonly) { + virBufferAddLit(&opt, ",cache=off"); + } + + if (virBufferError(&opt)) { + virReportOOMError(NULL); + goto error; + } + + return virBufferContentAndReset(&opt); + +error: + virBufferFreeAndReset(&opt); + return NULL; +} + + int qemuBuildNicStr(virConnectPtr conn, virDomainNetDefPtr net, @@ -1866,23 +1964,6 @@ no_memory: } -#define QEMU_SERIAL_PARAM_ACCEPTED_CHARS \ - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_" - -static int -qemuSafeSerialParamValue(virConnectPtr conn, - const char *value) -{ - if (strspn(value, QEMU_SERIAL_PARAM_ACCEPTED_CHARS) != strlen (value)) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("driver serial '%s' contains unsafe characters"), - value); - return -1; - } - - return 0; -} - /* * Constructs a argv suitable for launching qemu with config defined * for a given virtual machine. @@ -2273,12 +2354,9 @@ int qemudBuildCommandLine(virConnectPtr conn, } for (i = 0 ; i < def->ndisks ; i++) { - virBuffer opt = VIR_BUFFER_INITIALIZER; char *optstr; int bootable = 0; virDomainDiskDefPtr disk = def->disks[i]; - int idx = virDiskNameToIndex(disk->dst); - const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus); if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) { if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) { @@ -2291,14 +2369,6 @@ int qemudBuildCommandLine(virConnectPtr conn, continue; } - ADD_ARG_SPACE; - - if (idx < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("unsupported disk type '%s'"), disk->dst); - goto error; - } - switch (disk->device) { case VIR_DOMAIN_DISK_DEVICE_CDROM: bootable = bootCD; @@ -2314,69 +2384,10 @@ int qemudBuildCommandLine(virConnectPtr conn, break; } - if (disk->src) { - if (disk->type == VIR_DOMAIN_DISK_TYPE_DIR) { - /* QEMU only supports magic FAT format for now */ - if (disk->driverType && - STRNEQ(disk->driverType, "fat")) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("unsupported disk driver type for '%s'"), - disk->driverType); - goto error; - } - if (!disk->readonly) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s", - _("cannot create virtual FAT disks in read-write mode")); - goto error; - } - if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) - virBufferVSprintf(&opt, "file=fat:floppy:%s,", disk->src); - else - virBufferVSprintf(&opt, "file=fat:%s,", disk->src); - } else { - virBufferVSprintf(&opt, "file=%s,", disk->src); - } - } - virBufferVSprintf(&opt, "if=%s", bus); - if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) - virBufferAddLit(&opt, ",media=cdrom"); - virBufferVSprintf(&opt, ",index=%d", idx); - if (bootable && - disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) - virBufferAddLit(&opt, ",boot=on"); - if (disk->driverType && - disk->type != VIR_DOMAIN_DISK_TYPE_DIR && - qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_FORMAT) - virBufferVSprintf(&opt, ",format=%s", disk->driverType); - if (disk->serial && - (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_SERIAL)) { - if (qemuSafeSerialParamValue(conn, disk->serial) < 0) - goto error; - virBufferVSprintf(&opt, ",serial=%s", disk->serial); - } - - if (disk->cachemode) { - const char *mode = - (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_CACHE_V2) ? - qemuDiskCacheV2TypeToString(disk->cachemode) : - qemuDiskCacheV1TypeToString(disk->cachemode); - - virBufferVSprintf(&opt, ",cache=%s", mode); - } else if (disk->shared && !disk->readonly) { - virBufferAddLit(&opt, ",cache=off"); - } + ADD_ARG_LIT("-drive"); - if (virBufferError(&opt)) { - virBufferFreeAndReset(&opt); - goto no_memory; - } - - optstr = virBufferContentAndReset(&opt); - - if ((qargv[qargc++] = strdup("-drive")) == NULL) { - VIR_FREE(optstr); - goto no_memory; - } + if (!(optstr = qemuBuildDriveStr(disk, bootable, qemuCmdFlags))) + goto error; ADD_ARG(optstr); } } else { diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 82254ca..3dbe1c8 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -193,6 +193,11 @@ int qemuBuildNicStr (virConnectPtr conn, int vlan, char **str); + +char * qemuBuildDriveStr (virDomainDiskDefPtr disk, + int bootable, + int qemuCmdFlags); + int qemudNetworkIfaceConnect (virConnectPtr conn, struct qemud_driver *driver, virDomainNetDefPtr net, -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:04PM +0000, Daniel P. Berrange wrote:
To enable it to be called from multiple locations, split out the code for building the -drive arg string. This will be needed by later patches which do drive hotplug, the conversion to use -device, and the conversion to controller/bus/unit addressing
* src/qemu/qemu_conf.c, src/qemu/qemu_conf.h: Add qemuBuildDriveStr for building -drive arg string --- src/qemu/qemu_conf.c | 191 ++++++++++++++++++++++++++----------------------- src/qemu/qemu_conf.h | 5 ++ 2 files changed, 106 insertions(+), 90 deletions(-)
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

The current code for using -drive simply sets the -drive 'index' parameter. QEMU internally converts this to bus/unit depending on the type of drive. This does not give us precise control over the bus/unit assignment though. This change switches over to make libvirt explicitly calculate the bus/unit number. In addition bus/unit/index are actually irrelevant for VirtIO disks, since each virtio disk is a separate PCI device. No disk controller is involved. Doing the conversion to bus/unit in libvirt allows us to correctly attach SCSI controllers when required. * src/qemu/qemu_conf.c: Specify bus/unit instead of index for disks * tests/qemuxml2argvdata/qemuxml2argv-disk*.args: Switch over from using index=NNNN, to bus=NN, unit=NN for SCSI/IDE/Floppy disks --- src/qemu/qemu_conf.c | 134 +++++++++++++++++++- .../qemuxml2argv-disk-cdrom-empty.args | 2 +- .../qemuxml2argv-disk-drive-boot-cdrom.args | 2 +- .../qemuxml2argv-disk-drive-boot-disk.args | 2 +- .../qemuxml2argv-disk-drive-cache-v1-none.args | 2 +- .../qemuxml2argv-disk-drive-cache-v1-wb.args | 2 +- .../qemuxml2argv-disk-drive-cache-v1-wt.args | 2 +- .../qemuxml2argv-disk-drive-cache-v2-none.args | 2 +- .../qemuxml2argv-disk-drive-cache-v2-wb.args | 2 +- .../qemuxml2argv-disk-drive-cache-v2-wt.args | 2 +- .../qemuxml2argv-disk-drive-fat.args | 2 +- .../qemuxml2argv-disk-drive-fmt-qcow.args | 2 +- .../qemuxml2argv-disk-drive-shared.args | 2 +- .../qemuxml2argvdata/qemuxml2argv-disk-virtio.args | 2 +- .../qemuxml2argvdata/qemuxml2argv-disk-virtio.xml | 2 +- .../qemuxml2argvdata/qemuxml2argv-disk-xenvbd.args | 2 +- .../qemuxml2argv-floppy-drive-fat.args | 2 +- 17 files changed, 145 insertions(+), 21 deletions(-) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 94f4cc0..26baece 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1549,6 +1549,7 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk, virBuffer opt = VIR_BUFFER_INITIALIZER; const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus); int idx = virDiskNameToIndex(disk->dst); + int busid = -1, unitid = -1; if (idx < 0) { qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, @@ -1556,6 +1557,74 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk, goto error; } + switch (disk->bus) { + case VIR_DOMAIN_DISK_BUS_SCSI: + if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s", + _("unexpected address type for scsi disk")); + goto error; + } + + /* Setting bus= attr for SCSI drives, causes a controller + * to be created. Yes this is slightly odd. It is not possible + * to have > 1 bus on a SCSI controller (yet). */ + if (disk->info.addr.drive.bus != 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("SCSI controller only supports 1 bus")); + goto error; + } + busid = disk->info.addr.drive.controller; + unitid = disk->info.addr.drive.unit; + break; + + case VIR_DOMAIN_DISK_BUS_IDE: + if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s", + _("unexpected address type for ide disk")); + goto error; + } + /* We can only have 1 IDE controller (currently) */ + if (disk->info.addr.drive.controller != 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("Only 1 %s controller is supported"), bus); + goto error; + } + busid = disk->info.addr.drive.bus; + unitid = disk->info.addr.drive.unit; + break; + + case VIR_DOMAIN_DISK_BUS_FDC: + if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s", + _("unexpected address type for fdc disk")); + goto error; + } + /* We can only have 1 FDC controller (currently) */ + if (disk->info.addr.drive.controller != 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("Only 1 %s controller is supported"), bus); + goto error; + } + /* We can only have 1 FDC bus (currently) */ + if (disk->info.addr.drive.bus != 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("Only 1 %s bus is supported"), bus); + goto error; + } + unitid = disk->info.addr.drive.unit; + + break; + + case VIR_DOMAIN_DISK_BUS_VIRTIO: + /* Each virtio drive is a separate PCI device, no unit/busid or index */ + idx = -1; + break; + + case VIR_DOMAIN_DISK_BUS_XEN: + /* Xen has no address type currently, so assign based on index */ + break; + } + if (disk->src) { if (disk->type == VIR_DOMAIN_DISK_TYPE_DIR) { /* QEMU only supports magic FAT format for now */ @@ -1582,7 +1651,15 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk, virBufferVSprintf(&opt, "if=%s", bus); if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) virBufferAddLit(&opt, ",media=cdrom"); - virBufferVSprintf(&opt, ",index=%d", idx); + if (busid == -1 && unitid == -1) { + if (idx != -1) + virBufferVSprintf(&opt, ",index=%d", idx); + } else { + if (busid != -1) + virBufferVSprintf(&opt, ",bus=%d", busid); + if (unitid != -1) + virBufferVSprintf(&opt, ",unit=%d", unitid); + } if (bootable && disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) virBufferAddLit(&opt, ",boot=on"); @@ -3162,7 +3239,8 @@ error: */ static virDomainDiskDefPtr qemuParseCommandLineDisk(virConnectPtr conn, - const char *val) + const char *val, + int nvirtiodisk) { virDomainDiskDefPtr def = NULL; char **keywords; @@ -3170,6 +3248,8 @@ qemuParseCommandLineDisk(virConnectPtr conn, int nkeywords; int i; int idx = -1; + int busid = -1; + int unitid = -1; if ((nkeywords = qemuParseCommandLineKeywords(conn, val, &keywords, @@ -3239,6 +3319,22 @@ qemuParseCommandLineDisk(virConnectPtr conn, _("cannot parse drive index '%s'"), val); goto cleanup; } + } else if (STREQ(keywords[i], "bus")) { + if (virStrToLong_i(values[i], NULL, 10, &busid) < 0) { + virDomainDiskDefFree(def); + def = NULL; + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("cannot parse drive bus '%s'"), val); + goto cleanup; + } + } else if (STREQ(keywords[i], "unit")) { + if (virStrToLong_i(values[i], NULL, 10, &unitid) < 0) { + virDomainDiskDefFree(def); + def = NULL; + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("cannot parse drive unit '%s'"), val); + goto cleanup; + } } } @@ -3250,14 +3346,38 @@ qemuParseCommandLineDisk(virConnectPtr conn, def = NULL; goto cleanup; } - if (idx == -1) { + if (idx == -1 && + def->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) + idx = nvirtiodisk; + + if (idx == -1 && + unitid == -1 && + busid == -1) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("missing index parameter in drive '%s'"), val); + _("missing index/unit/bus parameter in drive '%s'"), val); virDomainDiskDefFree(def); def = NULL; goto cleanup; } + if (idx == -1) { + if (unitid == -1) + unitid = 0; + if (busid == -1) + busid = 0; + switch (def->bus) { + case VIR_DOMAIN_DISK_BUS_IDE: + idx = (busid * 2) + unitid; + break; + case VIR_DOMAIN_DISK_BUS_SCSI: + idx = (busid * 7) + unitid; + break; + default: + idx = unitid; + break; + } + } + if (def->bus == VIR_DOMAIN_DISK_BUS_IDE) { def->dst = strdup("hda"); } else if (def->bus == VIR_DOMAIN_DISK_BUS_SCSI) { @@ -3831,6 +3951,7 @@ virDomainDefPtr qemuParseCommandLine(virConnectPtr conn, int nnics = 0; const char **nics = NULL; int video = VIR_DOMAIN_VIDEO_TYPE_CIRRUS; + int nvirtiodisk = 0; if (!progargv[0]) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, @@ -4159,13 +4280,16 @@ virDomainDefPtr qemuParseCommandLine(virConnectPtr conn, } else if (STREQ(arg, "-drive")) { virDomainDiskDefPtr disk; WANT_VALUE(); - if (!(disk = qemuParseCommandLineDisk(conn, val))) + if (!(disk = qemuParseCommandLineDisk(conn, val, nvirtiodisk))) goto error; if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0) { virDomainDiskDefFree(disk); goto no_memory; } def->disks[def->ndisks++] = disk; + + if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) + nvirtiodisk++; } else if (STREQ(arg, "-pcidevice")) { virDomainHostdevDefPtr hostdev; WANT_VALUE(); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.args index 1dd90d0..44ba0ea 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0 -drive if=ide,media=cdrom,index=2 -net none -serial none -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0 -drive if=ide,media=cdrom,bus=1,unit=0 -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.args index 2612285..2bf268b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot d -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0 -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2 -net none -serial none -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot d -drive file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0 -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,bus=1,unit=0 -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.args index d1627ea..d81d6d3 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,boot=on -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2 -net none -serial none -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0,boot=on -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,bus=1,unit=0 -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.args index 611cd33..bdac2a4 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,format=qcow2,cache=off -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2,format=raw -net none -serial none -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0,format=qcow2,cache=off -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,bus=1,unit=0,format=raw -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.args index 05b68ca..8b14da1 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,format=qcow2,cache=on -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2,format=raw -net none -serial none -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0,format=qcow2,cache=on -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,bus=1,unit=0,format=raw -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.args index 611cd33..bdac2a4 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,format=qcow2,cache=off -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2,format=raw -net none -serial none -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0,format=qcow2,cache=off -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,bus=1,unit=0,format=raw -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.args index 6271491..1e1f292 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,format=qcow2,cache=none -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2,format=raw -net none -serial none -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0,format=qcow2,cache=none -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,bus=1,unit=0,format=raw -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.args index a9d979a..07bfc1e 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,format=qcow2,cache=writeback -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2,format=raw -net none -serial none -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0,format=qcow2,cache=writeback -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,bus=1,unit=0,format=raw -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.args index eb20a0e..fe18cec 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,format=qcow2,cache=writethrough -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2,format=raw -net none -serial none -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0,format=qcow2,cache=writethrough -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,bus=1,unit=0,format=raw -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.args index da1163b..39c2cc3 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=fat:/var/somefiles,if=ide,index=0,boot=on -net none -serial none -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=fat:/var/somefiles,if=ide,bus=0,unit=0,boot=on -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.args index d411c8c..79ba2c3 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,boot=on,format=qcow2 -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2,format=raw -net none -serial none -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0,boot=on,format=qcow2 -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,bus=1,unit=0,format=raw -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.args index 07cbe0e..0eade30 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,format=qcow2,serial=XYZXYZXYZYXXYZYZYXYZY,cache=off -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2,format=raw -net none -serial none -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0,format=qcow2,serial=XYZXYZXYZYXXYZYZYXYZY,cache=off -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,bus=1,unit=0,format=raw -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args index 70ccc16..2329cff 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,boot=on -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2 -drive file=/tmp/data.img,if=virtio,index=0 -drive file=/tmp/logs.img,if=virtio,index=6 -net none -serial none -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0,boot=on -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,bus=1,unit=0 -drive file=/tmp/data.img,if=virtio -drive file=/tmp/logs.img,if=virtio -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml index e506d9f..c6cf300 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml @@ -31,7 +31,7 @@ </disk> <disk type='file' device='disk'> <source file='/tmp/logs.img'/> - <target dev='vdg' bus='virtio'/> + <target dev='vdb' bus='virtio'/> </disk> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.args index 484eb80..a3b293a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,boot=on -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2 -drive file=/tmp/data.img,if=xen,index=0 -drive file=/tmp/logs.img,if=xen,index=6 -net none -serial none -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0,boot=on -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,bus=1,unit=0 -drive file=/tmp/data.img,if=xen,index=0 -drive file=/tmp/logs.img,if=xen,index=6 -net none -serial none -parallel none -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.args b/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.args index 4b4e3f4..0eb10d6 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot a -drive file=fat:floppy:/var/somefiles,if=floppy,index=0 -net none -serial none -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot a -drive file=fat:floppy:/var/somefiles,if=floppy,unit=0 -net none -serial none -parallel none -usb -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:05PM +0000, Daniel P. Berrange wrote:
The current code for using -drive simply sets the -drive 'index' parameter. QEMU internally converts this to bus/unit depending on the type of drive. This does not give us precise control over the bus/unit assignment though. This change switches over to make libvirt explicitly calculate the bus/unit number.
In addition bus/unit/index are actually irrelevant for VirtIO disks, since each virtio disk is a separate PCI device. No disk controller is involved.
Doing the conversion to bus/unit in libvirt allows us to correctly attach SCSI controllers when required.
* src/qemu/qemu_conf.c: Specify bus/unit instead of index for disks * tests/qemuxml2argvdata/qemuxml2argv-disk*.args: Switch over from using index=NNNN, to bus=NN, unit=NN for SCSI/IDE/Floppy disks
Hum, that's an importabt change, but I'm a bit surprized to not see any checking from the version or help message to detect support. Was full addressing implemented so long ago that we shouldn't check for it and try to detect at startup if it's missing ? Just wondering, not a blocker ! ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Fri, Jan 15, 2010 at 02:34:21PM +0100, Daniel Veillard wrote:
On Fri, Jan 08, 2010 at 05:23:05PM +0000, Daniel P. Berrange wrote:
The current code for using -drive simply sets the -drive 'index' parameter. QEMU internally converts this to bus/unit depending on the type of drive. This does not give us precise control over the bus/unit assignment though. This change switches over to make libvirt explicitly calculate the bus/unit number.
In addition bus/unit/index are actually irrelevant for VirtIO disks, since each virtio disk is a separate PCI device. No disk controller is involved.
Doing the conversion to bus/unit in libvirt allows us to correctly attach SCSI controllers when required.
* src/qemu/qemu_conf.c: Specify bus/unit instead of index for disks * tests/qemuxml2argvdata/qemuxml2argv-disk*.args: Switch over from using index=NNNN, to bus=NN, unit=NN for SCSI/IDE/Floppy disks
Hum, that's an importabt change, but I'm a bit surprized to not see any checking from the version or help message to detect support. Was full addressing implemented so long ago that we shouldn't check for it and try to detect at startup if it's missing ? Just wondering, not a blocker !
Yeah, it has supported this syntax for as long as -drive has existed so the check for '-drive' is sufficient Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

From: Wolfgang Mauerer <wolfgang.mauerer@siemens.com> This patch allows for explicit hotplug/unplug of SCSI controllers. Ordinarily this is not required, since QEMU/libvirt will attach a new SCSI controller whenever one is required. Allowing explicit hotplug of controllers though, enables the caller to specify a static PCI address, instead of auto-assigning the next available PCI slot. Or it will when we have static PCI addressing. This patch is derived from Wolfgang Mauerer's disk controller patch series. * src/qemu/qemu_driver.c: Support hotplug & unplug of SCSI controllers * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h, src/qemu/qemu_monitor_json.c, src/qemu/qemu_monitor_json.h, src/qemu/qemu_monitor_text.c, src/qemu/qemu_monitor_text.h: Add new API for attaching PCI SCSI controllers --- src/libvirt_private.syms | 2 + src/qemu/qemu_driver.c | 118 ++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor.c | 16 ++++++ src/qemu/qemu_monitor.h | 4 ++ src/qemu/qemu_monitor_json.c | 40 ++++++++++++++ src/qemu/qemu_monitor_json.h | 4 ++ src/qemu/qemu_monitor_text.c | 45 ++++++++++++++++ src/qemu/qemu_monitor_text.h | 5 ++ 8 files changed, 234 insertions(+), 0 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a346aa5..fa8825f 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -183,6 +183,8 @@ virDomainDeviceAddressIsValid; virDomainDevicePCIAddressIsValid; virDomainDeviceInfoIsSet; virDomainDeviceAddressClear; +virDomainControllerTypeToString; +virDomainControllerDefFree; # domain_event.h diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 8c2e6d6..9dcbe25 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -5111,6 +5111,45 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn, return ret; } +static int qemudDomainAttachPciControllerDevice(virConnectPtr conn, + struct qemud_driver *driver, + virDomainObjPtr vm, + virDomainControllerDefPtr def) +{ + int i, ret; + const char* type = virDomainControllerTypeToString(def->type); + qemuDomainObjPrivatePtr priv = vm->privateData; + + for (i = 0 ; i < vm->def->ncontrollers ; i++) { + if ((vm->def->controllers[i]->type == def->type) && + (vm->def->controllers[i]->idx == def->idx)) { + qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED, + _("target %s:%d already exists"), + type, def->idx); + return -1; + } + } + + if (VIR_REALLOC_N(vm->def->controllers, vm->def->ncontrollers+1) < 0) { + virReportOOMError(conn); + return -1; + } + + qemuDomainObjEnterMonitorWithDriver(driver, vm); + ret = qemuMonitorAttachPCIDiskController(priv->mon, + type, + &def->info.addr.pci); + qemuDomainObjExitMonitorWithDriver(driver, vm); + + if (ret == 0) { + def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + virDomainControllerInsertPreAlloced(vm->def, def); + } + + return ret; +} + + static int qemudDomainAttachUsbMassstorageDevice(virConnectPtr conn, struct qemud_driver *driver, virDomainObjPtr vm, @@ -5496,6 +5535,15 @@ static int qemudDomainAttachDevice(virDomainPtr dom, virCgroupDenyDevicePath(cgroup, dev->data.disk->src); } + } else if (dev->type == VIR_DOMAIN_DEVICE_CONTROLLER) { + if (dev->data.controller->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) { + ret = qemudDomainAttachPciControllerDevice(dom->conn, driver, vm, dev->data.controller); + } else { + qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT, + _("disk controller bus '%s' cannot be hotplugged."), + virDomainControllerTypeToString(dev->data.controller->type)); + /* fallthrough */ + } } else if (dev->type == VIR_DOMAIN_DEVICE_NET) { ret = qemudDomainAttachNetDevice(dom->conn, driver, vm, dev, qemuCmdFlags); } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) { @@ -5587,6 +5635,67 @@ cleanup: return ret; } +static int qemudDomainDetachPciControllerDevice(virConnectPtr conn, + struct qemud_driver *driver, + virDomainObjPtr vm, + virDomainDeviceDefPtr dev) +{ + int i, ret = -1; + virDomainControllerDefPtr detach = NULL; + qemuDomainObjPrivatePtr priv = vm->privateData; + + for (i = 0 ; i < vm->def->ncontrollers ; i++) { + if ((vm->def->controllers[i]->type == dev->data.controller->type) && + (vm->def->controllers[i]->idx == dev->data.controller->idx)) { + detach = vm->def->controllers[i]; + break; + } + } + + if (!detach) { + qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("disk controller %s:%d not found"), + virDomainControllerTypeToString(dev->data.controller->type), + dev->data.controller->idx); + goto cleanup; + } + + if (!virDomainDeviceAddressIsValid(&detach->info, + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) { + qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, "%s", + _("device cannot be detached without a PCI address")); + goto cleanup; + } + + qemuDomainObjEnterMonitorWithDriver(driver, vm); + if (qemuMonitorRemovePCIDevice(priv->mon, + &detach->info.addr.pci) < 0) { + qemuDomainObjExitMonitor(vm); + goto cleanup; + } + qemuDomainObjExitMonitorWithDriver(driver, vm); + + if (vm->def->ncontrollers > 1) { + memmove(vm->def->controllers + i, + vm->def->controllers + i + 1, + sizeof(*vm->def->controllers) * + (vm->def->ncontrollers - (i + 1))); + vm->def->ncontrollers--; + if (VIR_REALLOC_N(vm->def->controllers, vm->def->ncontrollers) < 0) { + /* ignore, harmless */ + } + } else { + VIR_FREE(vm->def->controllers); + vm->def->ncontrollers = 0; + } + virDomainControllerDefFree(detach); + + ret = 0; + +cleanup: + return ret; +} + static int qemudDomainDetachNetDevice(virConnectPtr conn, struct qemud_driver *driver, @@ -5838,6 +5947,15 @@ static int qemudDomainDetachDevice(virDomainPtr dom, VIR_WARN0("Fail to restore disk device ownership"); } else if (dev->type == VIR_DOMAIN_DEVICE_NET) { ret = qemudDomainDetachNetDevice(dom->conn, driver, vm, dev); + } else if (dev->type == VIR_DOMAIN_DEVICE_CONTROLLER) { + if (dev->data.controller->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) { + ret = qemudDomainDetachPciControllerDevice(dom->conn, driver, vm, dev); + } else { + qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT, + _("disk controller bus '%s' cannot be hotunplugged."), + virDomainControllerTypeToString(dev->data.controller->type)); + /* fallthrough */ + } } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) { ret = qemudDomainDetachHostDevice(dom->conn, driver, vm, dev); } else diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index caf2d35..dca8906 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1250,3 +1250,19 @@ int qemuMonitorGetPtyPaths(qemuMonitorPtr mon, return qemuMonitorTextGetPtyPaths(mon, paths); } + + +int qemuMonitorAttachPCIDiskController(qemuMonitorPtr mon, + const char *bus, + virDomainDevicePCIAddress *guestAddr) +{ + DEBUG("mon=%p, fd=%d type=%s", mon, mon->fd, bus); + int ret; + + if (mon->json) + ret = qemuMonitorJSONAttachPCIDiskController(mon, bus, guestAddr); + else + ret = qemuMonitorTextAttachPCIDiskController(mon, bus, guestAddr); + + return ret; +} diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index e0a0552..1096106 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -265,4 +265,8 @@ int qemuMonitorRemoveHostNetwork(qemuMonitorPtr mon, int qemuMonitorGetPtyPaths(qemuMonitorPtr mon, virHashTablePtr paths); +int qemuMonitorAttachPCIDiskController(qemuMonitorPtr mon, + const char *bus, + virDomainDevicePCIAddress *guestAddr); + #endif /* QEMU_MONITOR_H */ diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index e0a3225..14b8680 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -1482,3 +1482,43 @@ int qemuMonitorJSONRemoveHostNetwork(qemuMonitorPtr mon, virJSONValueFree(reply); return ret; } + + +int qemuMonitorJSONAttachPCIDiskController(qemuMonitorPtr mon, + const char *bus, + virDomainDevicePCIAddress *guestAddr) +{ + int ret; + virJSONValuePtr cmd; + virJSONValuePtr reply = NULL; + char *dev; + + memset(guestAddr, 0, sizeof(*guestAddr)); + + if (virAsprintf(&dev, "if=%s", bus) < 0) { + virReportOOMError(NULL); + return -1; + } + + cmd = qemuMonitorJSONMakeCommand("pci_add", + "s:pci_addr", "auto", + "s:type", "storage", + "s:opts", dev, + NULL); + VIR_FREE(dev); + if (!cmd) + return -1; + + ret = qemuMonitorJSONCommand(mon, cmd, &reply); + + if (ret == 0) + ret = qemuMonitorJSONCheckError(cmd, reply); + + if (ret == 0 && + qemuMonitorJSONGetGuestAddress(reply, guestAddr) < 0) + ret = -1; + + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 74d88b2..96eb68d 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -141,4 +141,8 @@ int qemuMonitorJSONRemoveHostNetwork(qemuMonitorPtr mon, int vlan, const char *netname); +int qemuMonitorJSONAttachPCIDiskController(qemuMonitorPtr mon, + const char *bus, + virDomainDevicePCIAddress *guestAddr); + #endif /* QEMU_MONITOR_JSON_H */ diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index 7c8b0a2..db3912e 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -1747,6 +1747,51 @@ int qemuMonitorTextGetPtyPaths(qemuMonitorPtr mon, ret = 0; cleanup: + VIR_FREE(cmd); + VIR_FREE(reply); + return ret; +} + + +int qemuMonitorTextAttachPCIDiskController(qemuMonitorPtr mon, + const char *bus, + virDomainDevicePCIAddress *guestAddr) +{ + char *cmd = NULL; + char *reply = NULL; + int tryOldSyntax = 0; + int ret = -1; + +try_command: + if (virAsprintf(&cmd, "pci_add %s storage if=%s", + (tryOldSyntax ? "0": "pci_addr=auto"), bus) < 0) { + virReportOOMError(NULL); + goto cleanup; + } + + if (qemuMonitorCommand(mon, cmd, &reply) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("cannot attach %s disk controller"), bus); + goto cleanup; + } + + if (qemuMonitorTextParsePciAddReply(mon, reply, guestAddr) < 0) { + if (!tryOldSyntax && strstr(reply, "invalid char in expression")) { + VIR_FREE(reply); + VIR_FREE(cmd); + tryOldSyntax = 1; + goto try_command; + } + + qemudReportError (NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("adding %s disk controller failed: %s"), bus, reply); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FREE(cmd); VIR_FREE(reply); return ret; } diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h index f1f2f77..ca2538a 100644 --- a/src/qemu/qemu_monitor_text.h +++ b/src/qemu/qemu_monitor_text.h @@ -148,4 +148,9 @@ int qemuMonitorTextRemoveHostNetwork(qemuMonitorPtr mon, int qemuMonitorTextGetPtyPaths(qemuMonitorPtr mon, virHashTablePtr paths); +int qemuMonitorTextAttachPCIDiskController(qemuMonitorPtr mon, + const char *bus, + virDomainDevicePCIAddress *guestAddr); + + #endif /* QEMU_MONITOR_TEXT_H */ -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:06PM +0000, Daniel P. Berrange wrote:
From: Wolfgang Mauerer <wolfgang.mauerer@siemens.com>
This patch allows for explicit hotplug/unplug of SCSI controllers. Ordinarily this is not required, since QEMU/libvirt will attach a new SCSI controller whenever one is required. Allowing explicit hotplug of controllers though, enables the caller to specify a static PCI address, instead of auto-assigning the next available PCI slot. Or it will when we have static PCI addressing.
This patch is derived from Wolfgang Mauerer's disk controller patch series.
* src/qemu/qemu_driver.c: Support hotplug & unplug of SCSI controllers * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h, src/qemu/qemu_monitor_json.c, src/qemu/qemu_monitor_json.h, src/qemu/qemu_monitor_text.c, src/qemu/qemu_monitor_text.h: Add new API for attaching PCI SCSI controllers --- src/libvirt_private.syms | 2 + src/qemu/qemu_driver.c | 118 ++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor.c | 16 ++++++ src/qemu/qemu_monitor.h | 4 ++ src/qemu/qemu_monitor_json.c | 40 ++++++++++++++ src/qemu/qemu_monitor_json.h | 4 ++ src/qemu/qemu_monitor_text.c | 45 ++++++++++++++++ src/qemu/qemu_monitor_text.h | 5 ++ 8 files changed, 234 insertions(+), 0 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a346aa5..fa8825f 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -183,6 +183,8 @@ virDomainDeviceAddressIsValid; virDomainDevicePCIAddressIsValid; virDomainDeviceInfoIsSet; virDomainDeviceAddressClear; +virDomainControllerTypeToString; +virDomainControllerDefFree;
# domain_event.h diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 8c2e6d6..9dcbe25 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -5111,6 +5111,45 @@ static int qemudDomainAttachPciDiskDevice(virConnectPtr conn, return ret; }
+static int qemudDomainAttachPciControllerDevice(virConnectPtr conn, + struct qemud_driver *driver, + virDomainObjPtr vm, + virDomainControllerDefPtr def) +{ + int i, ret; + const char* type = virDomainControllerTypeToString(def->type); + qemuDomainObjPrivatePtr priv = vm->privateData; + + for (i = 0 ; i < vm->def->ncontrollers ; i++) { + if ((vm->def->controllers[i]->type == def->type) && + (vm->def->controllers[i]->idx == def->idx)) { + qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED, + _("target %s:%d already exists"), + type, def->idx); + return -1; + } + } + + if (VIR_REALLOC_N(vm->def->controllers, vm->def->ncontrollers+1) < 0) { + virReportOOMError(conn); + return -1; + } + + qemuDomainObjEnterMonitorWithDriver(driver, vm); + ret = qemuMonitorAttachPCIDiskController(priv->mon, + type, + &def->info.addr.pci); + qemuDomainObjExitMonitorWithDriver(driver, vm); + + if (ret == 0) { + def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + virDomainControllerInsertPreAlloced(vm->def, def); + } + + return ret; +} + + static int qemudDomainAttachUsbMassstorageDevice(virConnectPtr conn, struct qemud_driver *driver, virDomainObjPtr vm, @@ -5496,6 +5535,15 @@ static int qemudDomainAttachDevice(virDomainPtr dom, virCgroupDenyDevicePath(cgroup, dev->data.disk->src); } + } else if (dev->type == VIR_DOMAIN_DEVICE_CONTROLLER) { + if (dev->data.controller->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) { + ret = qemudDomainAttachPciControllerDevice(dom->conn, driver, vm, dev->data.controller); + } else { + qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT, + _("disk controller bus '%s' cannot be hotplugged."), + virDomainControllerTypeToString(dev->data.controller->type)); + /* fallthrough */ + } } else if (dev->type == VIR_DOMAIN_DEVICE_NET) { ret = qemudDomainAttachNetDevice(dom->conn, driver, vm, dev, qemuCmdFlags); } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) { @@ -5587,6 +5635,67 @@ cleanup: return ret; }
+static int qemudDomainDetachPciControllerDevice(virConnectPtr conn, + struct qemud_driver *driver, + virDomainObjPtr vm, + virDomainDeviceDefPtr dev) +{ + int i, ret = -1; + virDomainControllerDefPtr detach = NULL; + qemuDomainObjPrivatePtr priv = vm->privateData; + + for (i = 0 ; i < vm->def->ncontrollers ; i++) { + if ((vm->def->controllers[i]->type == dev->data.controller->type) && + (vm->def->controllers[i]->idx == dev->data.controller->idx)) { + detach = vm->def->controllers[i]; + break; + } + } + + if (!detach) { + qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("disk controller %s:%d not found"), + virDomainControllerTypeToString(dev->data.controller->type), + dev->data.controller->idx); + goto cleanup; + } + + if (!virDomainDeviceAddressIsValid(&detach->info, + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) { + qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, "%s", + _("device cannot be detached without a PCI address")); + goto cleanup; + } + + qemuDomainObjEnterMonitorWithDriver(driver, vm); + if (qemuMonitorRemovePCIDevice(priv->mon, + &detach->info.addr.pci) < 0) { + qemuDomainObjExitMonitor(vm); + goto cleanup; + } + qemuDomainObjExitMonitorWithDriver(driver, vm); + + if (vm->def->ncontrollers > 1) { + memmove(vm->def->controllers + i, + vm->def->controllers + i + 1, + sizeof(*vm->def->controllers) * + (vm->def->ncontrollers - (i + 1))); + vm->def->ncontrollers--; + if (VIR_REALLOC_N(vm->def->controllers, vm->def->ncontrollers) < 0) { + /* ignore, harmless */ + } + } else { + VIR_FREE(vm->def->controllers); + vm->def->ncontrollers = 0; + } + virDomainControllerDefFree(detach); + + ret = 0; + +cleanup: + return ret; +} + static int qemudDomainDetachNetDevice(virConnectPtr conn, struct qemud_driver *driver, @@ -5838,6 +5947,15 @@ static int qemudDomainDetachDevice(virDomainPtr dom, VIR_WARN0("Fail to restore disk device ownership"); } else if (dev->type == VIR_DOMAIN_DEVICE_NET) { ret = qemudDomainDetachNetDevice(dom->conn, driver, vm, dev); + } else if (dev->type == VIR_DOMAIN_DEVICE_CONTROLLER) { + if (dev->data.controller->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) { + ret = qemudDomainDetachPciControllerDevice(dom->conn, driver, vm, dev); + } else { + qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT, + _("disk controller bus '%s' cannot be hotunplugged."), + virDomainControllerTypeToString(dev->data.controller->type)); + /* fallthrough */ + } } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) { ret = qemudDomainDetachHostDevice(dom->conn, driver, vm, dev); } else diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index caf2d35..dca8906 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1250,3 +1250,19 @@ int qemuMonitorGetPtyPaths(qemuMonitorPtr mon,
return qemuMonitorTextGetPtyPaths(mon, paths); } + + +int qemuMonitorAttachPCIDiskController(qemuMonitorPtr mon, + const char *bus, + virDomainDevicePCIAddress *guestAddr) +{ + DEBUG("mon=%p, fd=%d type=%s", mon, mon->fd, bus); + int ret; + + if (mon->json) + ret = qemuMonitorJSONAttachPCIDiskController(mon, bus, guestAddr); + else + ret = qemuMonitorTextAttachPCIDiskController(mon, bus, guestAddr); + + return ret; +} diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index e0a0552..1096106 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -265,4 +265,8 @@ int qemuMonitorRemoveHostNetwork(qemuMonitorPtr mon, int qemuMonitorGetPtyPaths(qemuMonitorPtr mon, virHashTablePtr paths);
+int qemuMonitorAttachPCIDiskController(qemuMonitorPtr mon, + const char *bus, + virDomainDevicePCIAddress *guestAddr); + #endif /* QEMU_MONITOR_H */ diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index e0a3225..14b8680 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -1482,3 +1482,43 @@ int qemuMonitorJSONRemoveHostNetwork(qemuMonitorPtr mon, virJSONValueFree(reply); return ret; } + + +int qemuMonitorJSONAttachPCIDiskController(qemuMonitorPtr mon, + const char *bus, + virDomainDevicePCIAddress *guestAddr) +{ + int ret; + virJSONValuePtr cmd; + virJSONValuePtr reply = NULL; + char *dev; + + memset(guestAddr, 0, sizeof(*guestAddr)); + + if (virAsprintf(&dev, "if=%s", bus) < 0) { + virReportOOMError(NULL); + return -1; + } + + cmd = qemuMonitorJSONMakeCommand("pci_add", + "s:pci_addr", "auto", + "s:type", "storage", + "s:opts", dev, + NULL); + VIR_FREE(dev); + if (!cmd) + return -1; + + ret = qemuMonitorJSONCommand(mon, cmd, &reply); + + if (ret == 0) + ret = qemuMonitorJSONCheckError(cmd, reply); + + if (ret == 0 && + qemuMonitorJSONGetGuestAddress(reply, guestAddr) < 0) + ret = -1; + + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 74d88b2..96eb68d 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -141,4 +141,8 @@ int qemuMonitorJSONRemoveHostNetwork(qemuMonitorPtr mon, int vlan, const char *netname);
+int qemuMonitorJSONAttachPCIDiskController(qemuMonitorPtr mon, + const char *bus, + virDomainDevicePCIAddress *guestAddr); + #endif /* QEMU_MONITOR_JSON_H */ diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index 7c8b0a2..db3912e 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -1747,6 +1747,51 @@ int qemuMonitorTextGetPtyPaths(qemuMonitorPtr mon, ret = 0;
cleanup: + VIR_FREE(cmd); + VIR_FREE(reply); + return ret; +} + + +int qemuMonitorTextAttachPCIDiskController(qemuMonitorPtr mon, + const char *bus, + virDomainDevicePCIAddress *guestAddr) +{ + char *cmd = NULL; + char *reply = NULL; + int tryOldSyntax = 0; + int ret = -1; + +try_command: + if (virAsprintf(&cmd, "pci_add %s storage if=%s", + (tryOldSyntax ? "0": "pci_addr=auto"), bus) < 0) { + virReportOOMError(NULL); + goto cleanup; + } + + if (qemuMonitorCommand(mon, cmd, &reply) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("cannot attach %s disk controller"), bus); + goto cleanup; + } + + if (qemuMonitorTextParsePciAddReply(mon, reply, guestAddr) < 0) { + if (!tryOldSyntax && strstr(reply, "invalid char in expression")) { + VIR_FREE(reply); + VIR_FREE(cmd); + tryOldSyntax = 1; + goto try_command; + } + + qemudReportError (NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("adding %s disk controller failed: %s"), bus, reply); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FREE(cmd); VIR_FREE(reply); return ret; } diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h index f1f2f77..ca2538a 100644 --- a/src/qemu/qemu_monitor_text.h +++ b/src/qemu/qemu_monitor_text.h @@ -148,4 +148,9 @@ int qemuMonitorTextRemoveHostNetwork(qemuMonitorPtr mon, int qemuMonitorTextGetPtyPaths(qemuMonitorPtr mon, virHashTablePtr paths);
+int qemuMonitorTextAttachPCIDiskController(qemuMonitorPtr mon, + const char *bus, + virDomainDevicePCIAddress *guestAddr); + + #endif /* QEMU_MONITOR_TEXT_H */
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

The current SCSI hotplug support attaches a brand new SCSI controller for every disk. This is broken because the semantics differ from those used when starting the VM initially. In the latter case, each SCSI controller is filled before a new one is added. If the user specifies an high drive index (sdazz) then at initial startup, many intermediate SCSI controllers may be added with no drives. This patch changes SCSI hotplug so that it exactly matches the behaviour of initial startup. First the SCSI controller number is determined for the drive to be hotplugged. If any controller upto and including that controller number is not yet present, it is attached. Then finally the drive is attached to the last controller. NB, this breaks SCSI hotunplug, because there is no 'drive_del' command in current QEMU. Previous SCSI hotunplug was broken in any case because it was unplugging the entire controller, not just the drive in question. A future QEMU will allow proper SCSI hotunplug of a drive. This patch is derived from work done by Wolfgang Mauerer on disk controllers. * src/qemu/qemu_driver.c: Fix SCSI hotplug to add a drive to the correct controller, instead of just attaching a new controller. * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h, src/qemu/qemu_monitor_json.c, src/qemu/qemu_monitor_json.h, src/qemu/qemu_monitor_text.c, src/qemu/qemu_monitor_text.h: Add support for 'drive_add' command --- src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 123 +++++++++++++++++++++++++++++++++++++++-- src/qemu/qemu_monitor.c | 20 +++++++ src/qemu/qemu_monitor.h | 5 ++ src/qemu/qemu_monitor_json.c | 81 +++++++++++++++++++++++++--- src/qemu/qemu_monitor_json.h | 5 ++ src/qemu/qemu_monitor_text.c | 102 ++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_text.h | 5 ++ 8 files changed, 329 insertions(+), 13 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index fa8825f..ad57c49 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -185,6 +185,7 @@ virDomainDeviceInfoIsSet; virDomainDeviceAddressClear; virDomainControllerTypeToString; virDomainControllerDefFree; +virDomainDeviceAddressTypeToString; # domain_event.h diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 9dcbe25..33c96d6 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -5149,6 +5149,116 @@ static int qemudDomainAttachPciControllerDevice(virConnectPtr conn, return ret; } +static virDomainControllerDefPtr +qemuDomainFindOrCreateSCSIDiskController(virConnectPtr conn, + struct qemud_driver *driver, + virDomainObjPtr vm, + int controller) +{ + int i; + virDomainControllerDefPtr cont; + for (i = 0 ; i < vm->def->ncontrollers ; i++) { + cont = vm->def->controllers[i]; + + if (cont->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) + continue; + + if (cont->idx == controller) + return cont; + } + + /* No SCSI controller present, for back compatability we + * now hotplug a controller */ + if (VIR_ALLOC(cont) < 0) { + virReportOOMError(conn); + return NULL; + } + cont->type = VIR_DOMAIN_CONTROLLER_TYPE_SCSI; + cont->idx = 0; + + VIR_INFO0("No SCSI controller present, hotplugging one"); + if (qemudDomainAttachPciControllerDevice(conn, driver, + vm, cont) < 0) { + VIR_FREE(cont); + return NULL; + } + return cont; +} + +static int qemudDomainAttachSCSIDisk(virConnectPtr conn, + struct qemud_driver *driver, + virDomainObjPtr vm, + virDomainDiskDefPtr dev, + int qemuCmdFlags) +{ + int i; + qemuDomainObjPrivatePtr priv = vm->privateData; + virDomainDeviceDriveAddress driveAddr; + virDomainControllerDefPtr cont; + char *drivestr = NULL; + int ret = -1; + + for (i = 0 ; i < vm->def->ndisks ; i++) { + if (STREQ(vm->def->disks[i]->dst, dev->dst)) { + qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED, + _("target %s already exists"), dev->dst); + goto cleanup; + } + } + + /* This func allocates the bus/unit IDs so must be before + * we search for controller + */ + if (!(drivestr = qemuBuildDriveStr(dev, 0, qemuCmdFlags))) + goto cleanup; + + + /* We should have an adddress now, so make sure */ + if (dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("unexpected disk address type %s"), + virDomainDeviceAddressTypeToString(dev->info.type)); + goto cleanup; + } + + for (i = 0 ; i < dev->info.addr.drive.controller ; i++) { + cont = qemuDomainFindOrCreateSCSIDiskController(conn, driver, vm, i); + if (!cont) + goto cleanup; + } + + if (cont->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("SCSI controller %d was missing its PCI address"), cont->idx); + goto cleanup; + } + + if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0) { + virReportOOMError(conn); + goto cleanup; + } + + qemuDomainObjEnterMonitorWithDriver(driver, vm); + ret = qemuMonitorAttachDrive(priv->mon, + drivestr, + &cont->info.addr.pci, + &driveAddr); + + qemuDomainObjExitMonitorWithDriver(driver, vm); + + if (ret == 0) { + /* XXX we should probably validate that the addr matches + * our existing defined addr instead of overwriting */ + dev->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE; + memcpy(&dev->info.addr.drive, &driveAddr, sizeof(driveAddr)); + virDomainDiskInsertPreAlloced(vm->def, dev); + } + +cleanup: + VIR_FREE(drivestr); + return ret; +} + static int qemudDomainAttachUsbMassstorageDevice(virConnectPtr conn, struct qemud_driver *driver, @@ -5514,9 +5624,10 @@ static int qemudDomainAttachDevice(virDomainPtr dom, if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_USB) { ret = qemudDomainAttachUsbMassstorageDevice(dom->conn, driver, vm, dev); - } else if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_SCSI || - dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) { + } else if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) { ret = qemudDomainAttachPciDiskDevice(dom->conn, driver, vm, dev); + } else if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) { + ret = qemudDomainAttachSCSIDisk(dom->conn, driver, vm, dev->data.disk, qemuCmdFlags); } else { qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT, _("disk bus '%s' cannot be hotplugged."), @@ -5938,8 +6049,7 @@ static int qemudDomainDetachDevice(virDomainPtr dom, if (dev->type == VIR_DOMAIN_DEVICE_DISK && dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_DISK && - (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_SCSI || - dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO)) { + dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) { ret = qemudDomainDetachPciDiskDevice(dom->conn, driver, vm, dev); if (driver->securityDriver) driver->securityDriver->domainRestoreSecurityImageLabel(dom->conn, vm, dev->data.disk); @@ -5958,9 +6068,10 @@ static int qemudDomainDetachDevice(virDomainPtr dom, } } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) { ret = qemudDomainDetachHostDevice(dom->conn, driver, vm, dev); - } else + } else { qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT, - "%s", _("only SCSI or virtio disk device can be detached dynamically")); + "%s", _("This type of device cannot be hot unplugged")); + } if (!ret && virDomainSaveStatus(dom->conn, driver->caps, driver->stateDir, vm) < 0) ret = -1; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index dca8906..b6ffc26 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1266,3 +1266,23 @@ int qemuMonitorAttachPCIDiskController(qemuMonitorPtr mon, return ret; } + + +int qemuMonitorAttachDrive(qemuMonitorPtr mon, + const char *drivestr, + virDomainDevicePCIAddress *controllerAddr, + virDomainDeviceDriveAddress *driveAddr) +{ + DEBUG("mon=%p, fd=%d drivestr=%s domain=%d bus=%d slot=%d function=%d", + mon, mon->fd, drivestr, + controllerAddr->domain, controllerAddr->bus, + controllerAddr->slot, controllerAddr->function); + int ret; + + if (mon->json) + ret = qemuMonitorJSONAttachDrive(mon, drivestr, controllerAddr, driveAddr); + else + ret = qemuMonitorTextAttachDrive(mon, drivestr, controllerAddr, driveAddr); + + return ret; +} diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 1096106..e270299 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -269,4 +269,9 @@ int qemuMonitorAttachPCIDiskController(qemuMonitorPtr mon, const char *bus, virDomainDevicePCIAddress *guestAddr); +int qemuMonitorAttachDrive(qemuMonitorPtr mon, + const char *drivestr, + virDomainDevicePCIAddress *controllerAddr, + virDomainDeviceDriveAddress *driveAddr); + #endif /* QEMU_MONITOR_H */ diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 14b8680..0ae8cd6 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -1203,10 +1203,9 @@ int qemuMonitorJSONAddUSBDeviceMatch(qemuMonitorPtr mon, } -/* XXX qemu also returns a 'function' number now */ static int -qemuMonitorJSONGetGuestAddress(virJSONValuePtr reply, - virDomainDevicePCIAddress *guestAddr) +qemuMonitorJSONGetGuestPCIAddress(virJSONValuePtr reply, + virDomainDevicePCIAddress *guestAddr) { virJSONValuePtr addr; @@ -1278,7 +1277,7 @@ int qemuMonitorJSONAddPCIHostDevice(qemuMonitorPtr mon, ret = qemuMonitorJSONCheckError(cmd, reply); if (ret == 0 && - qemuMonitorJSONGetGuestAddress(reply, guestAddr) < 0) + qemuMonitorJSONGetGuestPCIAddress(reply, guestAddr) < 0) ret = -1; virJSONValueFree(cmd); @@ -1319,7 +1318,7 @@ int qemuMonitorJSONAddPCIDisk(qemuMonitorPtr mon, ret = qemuMonitorJSONCheckError(cmd, reply); if (ret == 0 && - qemuMonitorJSONGetGuestAddress(reply, guestAddr) < 0) + qemuMonitorJSONGetGuestPCIAddress(reply, guestAddr) < 0) ret = -1; virJSONValueFree(cmd); @@ -1351,7 +1350,7 @@ int qemuMonitorJSONAddPCINetwork(qemuMonitorPtr mon, ret = qemuMonitorJSONCheckError(cmd, reply); if (ret == 0 && - qemuMonitorJSONGetGuestAddress(reply, guestAddr) < 0) + qemuMonitorJSONGetGuestPCIAddress(reply, guestAddr) < 0) ret = -1; virJSONValueFree(cmd); @@ -1515,7 +1514,75 @@ int qemuMonitorJSONAttachPCIDiskController(qemuMonitorPtr mon, ret = qemuMonitorJSONCheckError(cmd, reply); if (ret == 0 && - qemuMonitorJSONGetGuestAddress(reply, guestAddr) < 0) + qemuMonitorJSONGetGuestPCIAddress(reply, guestAddr) < 0) + ret = -1; + + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} + + +static int +qemuMonitorJSONGetGuestDriveAddress(virJSONValuePtr reply, + virDomainDeviceDriveAddress *driveAddr) +{ + virJSONValuePtr addr; + + addr = virJSONValueObjectGet(reply, "return"); + if (!addr || addr->type != VIR_JSON_TYPE_OBJECT) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("drive_add reply was missing device address")); + return -1; + } + + if (virJSONValueObjectGetNumberUint(addr, "bus", &driveAddr->bus) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("drive_add reply was missing device bus number")); + return -1; + } + + if (virJSONValueObjectGetNumberUint(addr, "unit", &driveAddr->unit) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("drive_add reply was missing device unit number")); + return -1; + } + + return 0; +} + + +int qemuMonitorJSONAttachDrive(qemuMonitorPtr mon, + const char *drivestr, + virDomainDevicePCIAddress* controllerAddr, + virDomainDeviceDriveAddress* driveAddr) +{ + int ret; + virJSONValuePtr cmd = NULL; + virJSONValuePtr reply = NULL; + char *dev; + + if (virAsprintf(&dev, "%.2x:%.2x.%.1x", + controllerAddr->bus, controllerAddr->slot, controllerAddr->function) < 0) { + virReportOOMError(NULL); + return -1; + } + + cmd = qemuMonitorJSONMakeCommand("drive_add", + "s:pci_addr", dev, + "s:opts", drivestr, + NULL); + VIR_FREE(dev); + if (!cmd) + return -1; + + ret = qemuMonitorJSONCommand(mon, cmd, &reply); + + if (ret == 0) + ret = qemuMonitorJSONCheckError(cmd, reply); + + if (ret == 0 && + qemuMonitorJSONGetGuestDriveAddress(reply, driveAddr) < 0) ret = -1; virJSONValueFree(cmd); diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 96eb68d..fcab483 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -145,4 +145,9 @@ int qemuMonitorJSONAttachPCIDiskController(qemuMonitorPtr mon, const char *bus, virDomainDevicePCIAddress *guestAddr); +int qemuMonitorJSONAttachDrive(qemuMonitorPtr mon, + const char *drivestr, + virDomainDevicePCIAddress *controllerAddr, + virDomainDeviceDriveAddress *driveAddr); + #endif /* QEMU_MONITOR_JSON_H */ diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index db3912e..c2c37b4 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -1795,3 +1795,105 @@ cleanup: VIR_FREE(reply); return ret; } + + +static int +qemudParseDriveAddReply(const char *reply, + virDomainDeviceDriveAddressPtr addr) +{ + char *s, *e; + + /* If the command succeeds qemu prints: + * OK bus X, unit Y + */ + + if (!(s = strstr(reply, "OK "))) + return -1; + + s += 3; + + if (STRPREFIX(s, "bus ")) { + s += strlen("bus "); + + if (virStrToLong_ui(s, &e, 10, &addr->bus) == -1) { + VIR_WARN(_("Unable to parse bus '%s'\n"), s); + return -1; + } + + if (!STRPREFIX(e, ", ")) { + VIR_WARN(_("Expected ', ' parsing drive_add reply '%s'\n"), s); + return -1; + } + s = e + 2; + } + + if (!STRPREFIX(s, "unit ")) { + VIR_WARN(_("Expected 'unit ' parsing drive_add reply '%s'\n"), s); + return -1; + } + s += strlen("bus "); + + if (virStrToLong_ui(s, &e, 10, &addr->unit) == -1) { + VIR_WARN(_("Unable to parse unit number '%s'\n"), s); + return -1; + } + + return 0; +} + + +int qemuMonitorTextAttachDrive(qemuMonitorPtr mon, + const char *drivestr, + virDomainDevicePCIAddress *controllerAddr, + virDomainDeviceDriveAddress *driveAddr) +{ + char *cmd = NULL; + char *reply = NULL; + int ret = -1; + char *safe_str; + int tryOldSyntax = 0; + + safe_str = qemuMonitorEscapeArg(drivestr); + if (!safe_str) { + virReportOOMError(NULL); + return -1; + } + +try_command: + ret = virAsprintf(&cmd, "drive_add %s%.2x:%.2x:%.2x %s", + (tryOldSyntax ? "" : "pci_addr="), + controllerAddr->domain, controllerAddr->bus, + controllerAddr->slot, safe_str); + if (ret == -1) { + virReportOOMError(NULL); + goto cleanup; + } + + if (qemuMonitorCommand(mon, cmd, &reply) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("failed to close fd in qemu with '%s'"), cmd); + goto cleanup; + } + + if (qemudParseDriveAddReply(reply, driveAddr) < 0) { + if (!tryOldSyntax && strstr(reply, "invalid char in expression")) { + VIR_FREE(reply); + tryOldSyntax = 1; + goto try_command; + } + qemudReportError (NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("adding %s disk failed: %s"), drivestr, reply); + VIR_FREE(reply); + return -1; + } + + ret = 0; + +cleanup: + VIR_FREE(cmd); + VIR_FREE(reply); + VIR_FREE(safe_str); + return ret; +} + + diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h index ca2538a..4648ba1 100644 --- a/src/qemu/qemu_monitor_text.h +++ b/src/qemu/qemu_monitor_text.h @@ -152,5 +152,10 @@ int qemuMonitorTextAttachPCIDiskController(qemuMonitorPtr mon, const char *bus, virDomainDevicePCIAddress *guestAddr); +int qemuMonitorTextAttachDrive(qemuMonitorPtr mon, + const char *drivestr, + virDomainDevicePCIAddress *controllerAddr, + virDomainDeviceDriveAddress *driveAddr); + #endif /* QEMU_MONITOR_TEXT_H */ -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:07PM +0000, Daniel P. Berrange wrote:
The current SCSI hotplug support attaches a brand new SCSI controller for every disk. This is broken because the semantics differ from those used when starting the VM initially. In the latter case, each SCSI controller is filled before a new one is added.
If the user specifies an high drive index (sdazz) then at initial startup, many intermediate SCSI controllers may be added with no drives.
Argh, okay :-)
This patch changes SCSI hotplug so that it exactly matches the behaviour of initial startup. First the SCSI controller number is determined for the drive to be hotplugged. If any controller upto and including that controller number is not yet present, it is attached. Then finally the drive is attached to the last controller.
NB, this breaks SCSI hotunplug, because there is no 'drive_del' command in current QEMU. Previous SCSI hotunplug was broken in any case because it was unplugging the entire controller, not just the drive in question.
A future QEMU will allow proper SCSI hotunplug of a drive.
This patch is derived from work done by Wolfgang Mauerer on disk controllers.
* src/qemu/qemu_driver.c: Fix SCSI hotplug to add a drive to the correct controller, instead of just attaching a new controller. * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h, src/qemu/qemu_monitor_json.c, src/qemu/qemu_monitor_json.h, src/qemu/qemu_monitor_text.c, src/qemu/qemu_monitor_text.h: Add support for 'drive_add' command --- src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 123 +++++++++++++++++++++++++++++++++++++++-- src/qemu/qemu_monitor.c | 20 +++++++ src/qemu/qemu_monitor.h | 5 ++ src/qemu/qemu_monitor_json.c | 81 +++++++++++++++++++++++++--- src/qemu/qemu_monitor_json.h | 5 ++ src/qemu/qemu_monitor_text.c | 102 ++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_text.h | 5 ++ 8 files changed, 329 insertions(+), 13 deletions(-) [...] +static virDomainControllerDefPtr +qemuDomainFindOrCreateSCSIDiskController(virConnectPtr conn, + struct qemud_driver *driver, + virDomainObjPtr vm, + int controller) +{ + int i; + virDomainControllerDefPtr cont; + for (i = 0 ; i < vm->def->ncontrollers ; i++) { + cont = vm->def->controllers[i]; + + if (cont->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) + continue; + + if (cont->idx == controller) + return cont; + } + + /* No SCSI controller present, for back compatability we + * now hotplug a controller */ + if (VIR_ALLOC(cont) < 0) { + virReportOOMError(conn); + return NULL; + } + cont->type = VIR_DOMAIN_CONTROLLER_TYPE_SCSI; + cont->idx = 0; + + VIR_INFO0("No SCSI controller present, hotplugging one"); + if (qemudDomainAttachPciControllerDevice(conn, driver, + vm, cont) < 0) { + VIR_FREE(cont); + return NULL; + } + return cont; +}
cosmetic change, formatting the comment and blank line after argument declaration, if you can sneak it in
@@ -1515,7 +1514,75 @@ int qemuMonitorJSONAttachPCIDiskController(qemuMonitorPtr mon, ret = qemuMonitorJSONCheckError(cmd, reply);
if (ret == 0 && - qemuMonitorJSONGetGuestAddress(reply, guestAddr) < 0) + qemuMonitorJSONGetGuestPCIAddress(reply, guestAddr) < 0) + ret = -1; + + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +}
Hum, looks like a leak plug too here, or I got confused by the patch
+ if (ret == 0 && + qemuMonitorJSONGetGuestDriveAddress(reply, driveAddr) < 0) ret = -1;
virJSONValueFree(cmd);
okay probably a patch side effect
+static int +qemudParseDriveAddReply(const char *reply, + virDomainDeviceDriveAddressPtr addr) +{ + char *s, *e; + + /* If the command succeeds qemu prints: + * OK bus X, unit Y + */ + + if (!(s = strstr(reply, "OK "))) + return -1; + + s += 3;
I would rather search for "bus " in the string here
+ if (STRPREFIX(s, "bus ")) { + s += strlen("bus "); + + if (virStrToLong_ui(s, &e, 10, &addr->bus) == -1) { + VIR_WARN(_("Unable to parse bus '%s'\n"), s); + return -1; + } + + if (!STRPREFIX(e, ", ")) { + VIR_WARN(_("Expected ', ' parsing drive_add reply '%s'\n"), s); + return -1; + } + s = e + 2; + }
and then search for "unit " for inceased flexibility
+ if (!STRPREFIX(s, "unit ")) { + VIR_WARN(_("Expected 'unit ' parsing drive_add reply '%s'\n"), s); + return -1; + } + s += strlen("bus "); + + if (virStrToLong_ui(s, &e, 10, &addr->unit) == -1) { + VIR_WARN(_("Unable to parse unit number '%s'\n"), s); + return -1; + } + + return 0; +}
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Hotunplug of devices requires that we know their PCI address. Even hotplug of SCSI drives, required that we know the PCI address of the SCSI controller to attach the drive to. We can find this out by running 'info pci' and then correlating the vendor/product IDs with the devices we booted with. Although this approach is somewhat fragile, it is the only viable option with QEMU < 0.12, since there is no way for libvirto set explicit PCI addresses when creating devices in the first place. For QEMU > 0.12, this code will not be used. * src/qemu/qemu_driver.c: Assign all dynamic PCI addresses on startup of QEMU VM, matching vendor/product IDs * src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h, src/qemu/qemu_monitor_json.c, src/qemu/qemu_monitor_json.h, src/qemu/qemu_monitor_text.c, src/qemu/qemu_monitor_text.h: Add API for fetching PCI device address mapping --- src/qemu/qemu_driver.c | 361 ++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor.c | 13 ++ src/qemu/qemu_monitor.h | 11 ++ src/qemu/qemu_monitor_json.c | 7 + src/qemu/qemu_monitor_json.h | 3 + src/qemu/qemu_monitor_text.c | 129 +++++++++++++++ src/qemu/qemu_monitor_text.h | 2 + 7 files changed, 526 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 33c96d6..cd406ec 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1677,6 +1677,364 @@ qemuInitPasswords(struct qemud_driver *driver, } +#define QEMU_PCI_VENDOR_INTEL 0x8086 +#define QEMU_PCI_VENDOR_LSI_LOGIC 0x1000 +#define QEMU_PCI_VENDOR_REDHAT 0x1af4 +#define QEMU_PCI_VENDOR_CIRRUS 0x1013 +#define QEMU_PCI_VENDOR_REALTEK 0x10ec +#define QEMU_PCI_VENDOR_AMD 0x1022 +#define QEMU_PCI_VENDOR_ENSONIQ 0x1274 +#define QEMU_PCI_VENDOR_VMWARE 0x15ad +#define QEMU_PCI_VENDOR_QEMU 0x1234 + +#define QEMU_PCI_PRODUCT_DISK_VIRTIO 0x1001 + +#define QEMU_PCI_PRODUCT_NIC_NE2K 0x8029 +#define QEMU_PCI_PRODUCT_NIC_PCNET 0x2000 +#define QEMU_PCI_PRODUCT_NIC_RTL8139 0x8139 +#define QEMU_PCI_PRODUCT_NIC_E1000 0x100E +#define QEMU_PCI_PRODUCT_NIC_VIRTIO 0x1000 + +#define QEMU_PCI_PRODUCT_VGA_CIRRUS 0x00b8 +#define QEMU_PCI_PRODUCT_VGA_VMWARE 0x0405 +#define QEMU_PCI_PRODUCT_VGA_STDVGA 0x1111 + +#define QEMU_PCI_PRODUCT_AUDIO_AC97 0x2415 +#define QEMU_PCI_PRODUCT_AUDIO_ES1370 0x5000 + +#define QEMU_PCI_PRODUCT_CONTROLLER_PIIX 0x7010 +#define QEMU_PCI_PRODUCT_CONTROLLER_LSI 0x0012 + +#define QEMU_PCI_PRODUCT_WATCHDOG_I63000ESB 0x25ab + +static int +qemuAssignNextPCIAddress(virDomainDeviceInfo *info, + int vendor, + int product, + qemuMonitorPCIAddress *addrs, + int naddrs) +{ + int found = 0; + int i; + + VIR_DEBUG("Look for %x:%x out of %d", vendor, product, naddrs); + + for (i = 0 ; (i < naddrs) && !found; i++) { + VIR_DEBUG("Maybe %x:%x", addrs[i].vendor, addrs[i].product); + if (addrs[i].vendor == vendor && + addrs[i].product == product) { + VIR_DEBUG("Match %d", i); + found = 1; + break; + } + } + if (!found) { + return -1; + } + + /* Blank it out so this device isn't matched again */ + addrs[i].vendor = 0; + addrs[i].product = 0; + + if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + + if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + info->addr.pci.domain = addrs[i].addr.domain; + info->addr.pci.bus = addrs[i].addr.bus; + info->addr.pci.slot = addrs[i].addr.slot; + info->addr.pci.function = addrs[i].addr.function; + } + + return 0; +} + +static int +qemuGetPCIDiskVendorProduct(virDomainDiskDefPtr def, + unsigned *vendor, + unsigned *product) +{ + switch (def->bus) { + case VIR_DOMAIN_DISK_BUS_VIRTIO: + *vendor = QEMU_PCI_VENDOR_REDHAT; + *product = QEMU_PCI_PRODUCT_DISK_VIRTIO; + break; + + default: + return -1; + } + + return 0; +} + +static int +qemuGetPCINetVendorProduct(virDomainNetDefPtr def, + unsigned *vendor, + unsigned *product) +{ + if (!def->model) + return -1; + + if (STREQ(def->model, "ne2k_pci")) { + *vendor = QEMU_PCI_VENDOR_REALTEK; + *product = QEMU_PCI_PRODUCT_NIC_NE2K; + } else if (STREQ(def->model, "pcnet")) { + *vendor = QEMU_PCI_VENDOR_AMD; + *product = QEMU_PCI_PRODUCT_NIC_PCNET; + } else if (STREQ(def->model, "rtl8139")) { + *vendor = QEMU_PCI_VENDOR_REALTEK; + *product = QEMU_PCI_PRODUCT_NIC_RTL8139; + } else if (STREQ(def->model, "e1000")) { + *vendor = QEMU_PCI_VENDOR_INTEL; + *product = QEMU_PCI_PRODUCT_NIC_E1000; + } else if (STREQ(def->model, "virtio")) { + *vendor = QEMU_PCI_VENDOR_REDHAT; + *product = QEMU_PCI_PRODUCT_NIC_VIRTIO; + } else { + VIR_INFO("Unexpected NIC model %s, cannot get PCI address", + def->model); + return -1; + } + return 0; +} + +static int +qemuGetPCIControllerVendorProduct(virDomainControllerDefPtr def, + unsigned *vendor, + unsigned *product) +{ + switch (def->type) { + case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: + *vendor = QEMU_PCI_VENDOR_LSI_LOGIC; + *product = QEMU_PCI_PRODUCT_CONTROLLER_LSI; + break; + + case VIR_DOMAIN_CONTROLLER_TYPE_FDC: + /* XXX we could put in the ISA bridge address, but + that's not technically the FDC's address */ + return -1; + + case VIR_DOMAIN_CONTROLLER_TYPE_IDE: + *vendor = QEMU_PCI_VENDOR_INTEL; + *product = QEMU_PCI_PRODUCT_CONTROLLER_PIIX; + break; + + default: + VIR_INFO("Unexpected controller type %s, cannot get PCI address", + virDomainControllerTypeToString(def->type)); + return -1; + } + + return 0; +} + +static int +qemuGetPCIVideoVendorProduct(virDomainVideoDefPtr def, + unsigned *vendor, + unsigned *product) +{ + switch (def->type) { + case VIR_DOMAIN_VIDEO_TYPE_CIRRUS: + *vendor = QEMU_PCI_VENDOR_CIRRUS; + *product = QEMU_PCI_PRODUCT_VGA_CIRRUS; + break; + + case VIR_DOMAIN_VIDEO_TYPE_VGA: + *vendor = QEMU_PCI_VENDOR_QEMU; + *product = QEMU_PCI_PRODUCT_VGA_STDVGA; + break; + + case VIR_DOMAIN_VIDEO_TYPE_VMVGA: + *vendor = QEMU_PCI_VENDOR_VMWARE; + *product = QEMU_PCI_PRODUCT_VGA_VMWARE; + break; + + default: + return -1; + } + return 0; +} + +static int +qemuGetPCISoundVendorProduct(virDomainSoundDefPtr def, + unsigned *vendor, + unsigned *product) +{ + switch (def->model) { + case VIR_DOMAIN_SOUND_MODEL_ES1370: + *vendor = QEMU_PCI_VENDOR_ENSONIQ; + *product = QEMU_PCI_PRODUCT_AUDIO_ES1370; + break; + + case VIR_DOMAIN_SOUND_MODEL_AC97: + *vendor = QEMU_PCI_VENDOR_INTEL; + *product = QEMU_PCI_PRODUCT_AUDIO_AC97; + break; + + default: + return -1; + } + + return 0; +} + +static int +qemuGetPCIWatchdogVendorProduct(virDomainWatchdogDefPtr def, + unsigned *vendor, + unsigned *product) +{ + switch (def->model) { + case VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB: + *vendor = QEMU_PCI_VENDOR_INTEL; + *product = QEMU_PCI_PRODUCT_WATCHDOG_I63000ESB; + break; + + default: + return -1; + } + + return 0; +} + + +/* + * This entire method assumes that PCI devices in 'info pci' + * match ordering of devices specified on the command line + * wrt to devices of matching vendor+product + * + * XXXX this might not be a valid assumption if we assign + * some static addrs on CLI. Have to check that... + */ +static int +qemuAssignPCIAddresses(virDomainObjPtr vm, + qemuMonitorPCIAddress *addrs, + int naddrs) +{ + unsigned int vendor = 0, product = 0; + int i; + + /* XXX should all these vendor/product IDs be kept in the + * actual device data structure instead ? + */ + + for (i = 0 ; i < vm->def->ndisks ; i++) { + if (qemuGetPCIDiskVendorProduct(vm->def->disks[i], &vendor, &product) < 0) + continue; + + if (qemuAssignNextPCIAddress(&(vm->def->disks[i]->info), + vendor, product, + addrs, naddrs) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("cannot find PCI address for VirtIO disk %s"), + vm->def->disks[i]->dst); + return -1; + } + } + + for (i = 0 ; i < vm->def->nnets ; i++) { + if (qemuGetPCINetVendorProduct(vm->def->nets[i], &vendor, &product) < 0) + continue; + + if (qemuAssignNextPCIAddress(&(vm->def->nets[i]->info), + vendor, product, + addrs, naddrs) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("cannot find PCI address for %s NIC"), + vm->def->nets[i]->model); + return -1; + } + } + + for (i = 0 ; i < vm->def->ncontrollers ; i++) { + if (qemuGetPCIControllerVendorProduct(vm->def->controllers[i], &vendor, &product) < 0) + continue; + + if (qemuAssignNextPCIAddress(&(vm->def->controllers[i]->info), + vendor, product, + addrs, naddrs) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("cannot find PCI address for controller %s"), + virDomainControllerTypeToString(vm->def->controllers[i]->type)); + return -1; + } + } + + for (i = 0 ; i < vm->def->nvideos ; i++) { + if (qemuGetPCIVideoVendorProduct(vm->def->videos[i], &vendor, &product) < 0) + continue; + + if (qemuAssignNextPCIAddress(&(vm->def->videos[i]->info), + vendor, product, + addrs, naddrs) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("cannot find PCI address for video adapter %s"), + virDomainVideoTypeToString(vm->def->videos[i]->type)); + return -1; + } + } + + for (i = 0 ; i < vm->def->nsounds ; i++) { + if (qemuGetPCISoundVendorProduct(vm->def->sounds[i], &vendor, &product) < 0) + continue; + + if (qemuAssignNextPCIAddress(&(vm->def->sounds[i]->info), + vendor, product, + addrs, naddrs) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("cannot find PCI address for sound adapter %s"), + virDomainSoundModelTypeToString(vm->def->sounds[i]->model)); + return -1; + } + } + + + if (vm->def->watchdog && + qemuGetPCIWatchdogVendorProduct(vm->def->watchdog, &vendor, &product) == 0) { + if (qemuAssignNextPCIAddress(&(vm->def->watchdog->info), + vendor, product, + addrs, naddrs) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("cannot find PCI address for watchdog %s"), + virDomainWatchdogModelTypeToString(vm->def->watchdog->model)); + return -1; + } + } + + /* XXX console (virtio) */ + + + /* ... and now things we don't have in our xml */ + + /* XXX USB controller ? */ + + /* XXXX virtio balloon ? */ + + /* XXX what about other PCI devices (ie bridges) */ + + return 0; +} + +static int +qemuInitPCIAddresses(struct qemud_driver *driver, + virDomainObjPtr vm) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + int naddrs; + int ret; + qemuMonitorPCIAddress *addrs = NULL; + + qemuDomainObjEnterMonitorWithDriver(driver, vm); + naddrs = qemuMonitorGetAllPCIAddresses(priv->mon, + &addrs); + qemuDomainObjExitMonitorWithDriver(driver, vm); + + ret = qemuAssignPCIAddresses(vm, addrs, naddrs); + + VIR_FREE(addrs); + + return ret; +} + static int qemudNextFreeVNCPort(struct qemud_driver *driver ATTRIBUTE_UNUSED) { int i; @@ -2555,6 +2913,9 @@ static int qemudStartVMDaemon(virConnectPtr conn, if (qemuInitPasswords(driver, vm) < 0) goto abort; + if (qemuInitPCIAddresses(driver, vm) < 0) + goto abort; + qemuDomainObjEnterMonitorWithDriver(driver, vm); if (qemuMonitorSetBalloon(priv->mon, vm->def->memory) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index b6ffc26..031df30 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1286,3 +1286,16 @@ int qemuMonitorAttachDrive(qemuMonitorPtr mon, return ret; } + +int qemuMonitorGetAllPCIAddresses(qemuMonitorPtr mon, + qemuMonitorPCIAddress **addrs) +{ + DEBUG("mon=%p, fd=%d addrs=%p", mon, mon->fd, addrs); + int ret; + + if (mon->json) + ret = qemuMonitorJSONGetAllPCIAddresses(mon, addrs); + else + ret = qemuMonitorTextGetAllPCIAddresses(mon, addrs); + return ret; +} diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index e270299..8a405ce 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -274,4 +274,15 @@ int qemuMonitorAttachDrive(qemuMonitorPtr mon, virDomainDevicePCIAddress *controllerAddr, virDomainDeviceDriveAddress *driveAddr); + +typedef struct _qemuMonitorPCIAddress qemuMonitorPCIAddress; +struct _qemuMonitorPCIAddress { + unsigned int vendor; + unsigned int product; + virDomainDevicePCIAddress addr; +}; + +int qemuMonitorGetAllPCIAddresses(qemuMonitorPtr mon, + qemuMonitorPCIAddress **addrs); + #endif /* QEMU_MONITOR_H */ diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 0ae8cd6..cfea376 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -1589,3 +1589,10 @@ int qemuMonitorJSONAttachDrive(qemuMonitorPtr mon, virJSONValueFree(reply); return ret; } + + +int qemuMonitorJSONGetAllPCIAddresses(qemuMonitorPtr mon ATTRIBUTE_UNUSED, + qemuMonitorPCIAddress **addrs ATTRIBUTE_UNUSED) +{ + return -1; +} diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index fcab483..7db9785 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -150,4 +150,7 @@ int qemuMonitorJSONAttachDrive(qemuMonitorPtr mon, virDomainDevicePCIAddress *controllerAddr, virDomainDeviceDriveAddress *driveAddr); +int qemuMonitorJSONGetAllPCIAddresses(qemuMonitorPtr mon, + qemuMonitorPCIAddress **addrs); + #endif /* QEMU_MONITOR_JSON_H */ diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index c2c37b4..52cd97c 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -1897,3 +1897,132 @@ cleanup: } +/* + * The format we're after looks like this + * + * (qemu) info pci + * Bus 0, device 0, function 0: + * Host bridge: PCI device 8086:1237 + * id "" + * Bus 0, device 1, function 0: + * ISA bridge: PCI device 8086:7000 + * id "" + * Bus 0, device 1, function 1: + * IDE controller: PCI device 8086:7010 + * BAR4: I/O at 0xc000 [0xc00f]. + * id "" + * Bus 0, device 1, function 3: + * Bridge: PCI device 8086:7113 + * IRQ 9. + * id "" + * Bus 0, device 2, function 0: + * VGA controller: PCI device 1013:00b8 + * BAR0: 32 bit prefetchable memory at 0xf0000000 [0xf1ffffff]. + * BAR1: 32 bit memory at 0xf2000000 [0xf2000fff]. + * id "" + * Bus 0, device 3, function 0: + * Ethernet controller: PCI device 8086:100e + * IRQ 11. + * BAR0: 32 bit memory at 0xf2020000 [0xf203ffff]. + * BAR1: I/O at 0xc040 [0xc07f]. + * id "" + * + * Of this, we're interesting in the vendor/product ID + * and the bus/device/function data. + */ +#define CHECK_END(p) if (!(p)) break; +#define SKIP_TO(p, lbl) \ + (p) = strstr((p), (lbl)); \ + if (p) \ + (p) += strlen(lbl); +#define GET_INT(p, base, val) \ + if (virStrToLong_ui((p), &(p), (base), &(val)) < 0) { \ + qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, \ + _("cannot parse value for %s"), #val); \ + break; \ + } +#define SKIP_SPACE(p) \ + while (*(p) == ' ') (p)++; + +int qemuMonitorTextGetAllPCIAddresses(qemuMonitorPtr mon, + qemuMonitorPCIAddress **retaddrs) +{ + char *reply; + qemuMonitorPCIAddress *addrs = NULL; + int naddrs = 0; + char *p; + + *retaddrs = NULL; + + if (qemuMonitorCommand(mon, "info pci", &reply) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("cannot query PCI addresses")); + return -1; + } + + p = reply; + + + while (p) { + unsigned int bus, slot, func, vendor, product; + + SKIP_TO(p, " Bus"); + CHECK_END(p); + SKIP_SPACE(p); + GET_INT(p, 10, bus); + CHECK_END(p); + + SKIP_TO(p, ", device"); + CHECK_END(p); + SKIP_SPACE(p); + GET_INT(p, 10, slot); + CHECK_END(p); + + SKIP_TO(p, ", function"); + CHECK_END(p); + SKIP_SPACE(p); + GET_INT(p, 10, func); + CHECK_END(p); + + SKIP_TO(p, "PCI device"); + CHECK_END(p); + SKIP_SPACE(p); + GET_INT(p, 16, vendor); + CHECK_END(p); + + if (*p != ':') + break; + p++; + GET_INT(p, 16, product); + + if (VIR_REALLOC_N(addrs, naddrs+1) < 0) { + virReportOOMError(NULL); + goto error; + } + + addrs[naddrs].addr.domain = 0; + addrs[naddrs].addr.bus = bus; + addrs[naddrs].addr.slot = slot; + addrs[naddrs].addr.function = func; + addrs[naddrs].vendor = vendor; + addrs[naddrs].product = product; + naddrs++; + + VIR_DEBUG("Got dev %d:%d:%d %x:%x", bus, slot, func, vendor, product); + } + + VIR_FREE(reply); + + *retaddrs = addrs; + + return naddrs; + +error: + VIR_FREE(addrs); + VIR_FREE(reply); + return -1; +} +#undef GET_INT +#undef SKIP_SPACE +#undef CHECK_END +#undef SKIP_TO diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h index 4648ba1..d6e9ca1 100644 --- a/src/qemu/qemu_monitor_text.h +++ b/src/qemu/qemu_monitor_text.h @@ -157,5 +157,7 @@ int qemuMonitorTextAttachDrive(qemuMonitorPtr mon, virDomainDevicePCIAddress *controllerAddr, virDomainDeviceDriveAddress *driveAddr); +int qemuMonitorTextGetAllPCIAddresses(qemuMonitorPtr mon, + qemuMonitorPCIAddress **addrs); #endif /* QEMU_MONITOR_TEXT_H */ -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:08PM +0000, Daniel P. Berrange wrote:
Hotunplug of devices requires that we know their PCI address. Even hotplug of SCSI drives, required that we know the PCI address of the SCSI controller to attach the drive to. We can find this out by running 'info pci' and then correlating the vendor/product IDs with the devices we booted with.
Although this approach is somewhat fragile, it is the only viable option with QEMU < 0.12, since there is no way for libvirto set explicit PCI addresses when creating devices in the first place. For QEMU > 0.12, this code will not be used.
Okay, this looks a bit fragile, but a temporary measure, parsing code looked fine, ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

It is perfectly acceptable to have multiple sound devices of same type in guest configuration. If the underlying hypervisor does not like this, it is its job to complain, not the XML parser's * src/conf/domain_conf.c: Remove hack which deleted duplicated sound device models. * tests/xml2sexprdata/xml2sexpr-fv-sound.xml: Remove duplicate models --- src/conf/domain_conf.c | 11 ----------- tests/xml2sexprdata/xml2sexpr-fv-sound.xml | 3 --- 2 files changed, 0 insertions(+), 14 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index dd10f36..5caf2ca 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3756,23 +3756,12 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn, if (n && VIR_ALLOC_N(def->sounds, n) < 0) goto no_memory; for (i = 0 ; i < n ; i++) { - int collision = 0, j; virDomainSoundDefPtr sound = virDomainSoundDefParseXML(conn, nodes[i], flags); if (!sound) goto error; - /* Verify there's no duplicated sound card */ - for (j = 0 ; j < def->nsounds ; j++) { - if (def->sounds[j]->model == sound->model) - collision = 1; - } - if (collision) { - virDomainSoundDefFree(sound); - continue; - } - def->sounds[def->nsounds++] = sound; } VIR_FREE(nodes); diff --git a/tests/xml2sexprdata/xml2sexpr-fv-sound.xml b/tests/xml2sexprdata/xml2sexpr-fv-sound.xml index 0fe92fe..75c295c 100644 --- a/tests/xml2sexprdata/xml2sexpr-fv-sound.xml +++ b/tests/xml2sexprdata/xml2sexpr-fv-sound.xml @@ -32,9 +32,6 @@ </disk> <graphics type='vnc' port='5917' keymap='ja'/> <sound model='sb16'/> - <sound model='sb16'/> - <sound model='es1370'/> - <sound model='sb16'/> <sound model='es1370'/> </devices> </domain> -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:09PM +0000, Daniel P. Berrange wrote:
It is perfectly acceptable to have multiple sound devices of same type in guest configuration. If the underlying hypervisor does not like this, it is its job to complain, not the XML parser's
* src/conf/domain_conf.c: Remove hack which deleted duplicated sound device models. * tests/xml2sexprdata/xml2sexpr-fv-sound.xml: Remove duplicate models --- src/conf/domain_conf.c | 11 ----------- tests/xml2sexprdata/xml2sexpr-fv-sound.xml | 3 --- 2 files changed, 0 insertions(+), 14 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index dd10f36..5caf2ca 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3756,23 +3756,12 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn, if (n && VIR_ALLOC_N(def->sounds, n) < 0) goto no_memory; for (i = 0 ; i < n ; i++) { - int collision = 0, j; virDomainSoundDefPtr sound = virDomainSoundDefParseXML(conn, nodes[i], flags); if (!sound) goto error;
- /* Verify there's no duplicated sound card */ - for (j = 0 ; j < def->nsounds ; j++) { - if (def->sounds[j]->model == sound->model) - collision = 1; - } - if (collision) { - virDomainSoundDefFree(sound); - continue; - } - def->sounds[def->nsounds++] = sound; } VIR_FREE(nodes); diff --git a/tests/xml2sexprdata/xml2sexpr-fv-sound.xml b/tests/xml2sexprdata/xml2sexpr-fv-sound.xml index 0fe92fe..75c295c 100644 --- a/tests/xml2sexprdata/xml2sexpr-fv-sound.xml +++ b/tests/xml2sexprdata/xml2sexpr-fv-sound.xml @@ -32,9 +32,6 @@ </disk> <graphics type='vnc' port='5917' keymap='ja'/> <sound model='sb16'/> - <sound model='sb16'/> - <sound model='es1370'/> - <sound model='sb16'/> <sound model='es1370'/> </devices> </domain>
makes sense, ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Temp hack --- src/qemu/qemu_monitor_text.c | 9 +++------ 1 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index 52cd97c..2b8c1e8 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -1678,14 +1678,12 @@ cleanup: int qemuMonitorTextGetPtyPaths(qemuMonitorPtr mon, virHashTablePtr paths) { - const char *cmd = "info chardev"; char *reply = NULL; int ret = -1; - if (qemuMonitorCommand(mon, cmd, &reply) < 0) { - qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, - _("failed to retrieve chardev info in qemu with '%s'"), - cmd); + if (qemuMonitorCommand(mon, "info chardev", &reply) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, "%s", + _("failed to retrieve chardev info in qemu with 'info chardev'")); goto cleanup; } @@ -1747,7 +1745,6 @@ int qemuMonitorTextGetPtyPaths(qemuMonitorPtr mon, ret = 0; cleanup: - VIR_FREE(cmd); VIR_FREE(reply); return ret; } -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:10PM +0000, Daniel P. Berrange wrote:
Temp hack --- src/qemu/qemu_monitor_text.c | 9 +++------ 1 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index 52cd97c..2b8c1e8 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -1678,14 +1678,12 @@ cleanup: int qemuMonitorTextGetPtyPaths(qemuMonitorPtr mon, virHashTablePtr paths) { - const char *cmd = "info chardev"; char *reply = NULL; int ret = -1;
- if (qemuMonitorCommand(mon, cmd, &reply) < 0) { - qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, - _("failed to retrieve chardev info in qemu with '%s'"), - cmd); + if (qemuMonitorCommand(mon, "info chardev", &reply) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, "%s", + _("failed to retrieve chardev info in qemu with 'info chardev'")); goto cleanup; }
@@ -1747,7 +1745,6 @@ int qemuMonitorTextGetPtyPaths(qemuMonitorPtr mon, ret = 0;
cleanup: - VIR_FREE(cmd); VIR_FREE(reply); return ret; }
Looks strictly equivalent, ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Fri, Jan 15, 2010 at 04:17:44PM +0100, Daniel Veillard wrote:
On Fri, Jan 08, 2010 at 05:23:10PM +0000, Daniel P. Berrange wrote:
Temp hack --- src/qemu/qemu_monitor_text.c | 9 +++------ 1 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index 52cd97c..2b8c1e8 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -1678,14 +1678,12 @@ cleanup: int qemuMonitorTextGetPtyPaths(qemuMonitorPtr mon, virHashTablePtr paths) { - const char *cmd = "info chardev"; char *reply = NULL; int ret = -1;
- if (qemuMonitorCommand(mon, cmd, &reply) < 0) { - qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, - _("failed to retrieve chardev info in qemu with '%s'"), - cmd); + if (qemuMonitorCommand(mon, "info chardev", &reply) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, "%s", + _("failed to retrieve chardev info in qemu with 'info chardev'")); goto cleanup; }
@@ -1747,7 +1745,6 @@ int qemuMonitorTextGetPtyPaths(qemuMonitorPtr mon, ret = 0;
cleanup: - VIR_FREE(cmd); VIR_FREE(reply); return ret; }
Looks strictly equivalent, ACK,
Sorry, this commit message should not have been left like this. There is one subtle difference. The original code is free()ing a 'constant' string. This is pretty much a guarenteed SEGV in malloc code. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

Existing applications using libvirt are not aware of the disk controller concept. Thus, after parsing the <disk> definitions in the XML, it is neccessary to create <controller> elements to satisfy all requested disks, as per their defined drive addresses * src/conf/domain_conf.c, src/conf/domain_conf.h, src/libvirt_private.syms: Add virDomainDefAddDiskControllers() method for populating disk controllers, and call it after parsing disk definitions. * src/qemu/qemu_conf.c: Call virDomainDefAddDiskControllers() when doing ARGV -> XML conversion * tests/qemuxml2argvdata/qemuxml2argv*.xml: Add disk controller data to all data files which don't have it already --- src/conf/domain_conf.c | 96 ++++++++++++++++++++ src/conf/domain_conf.h | 2 + src/libvirt_private.syms | 1 + src/qemu/qemu_conf.c | 3 + tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml | 1 + .../qemuxml2argvdata/qemuxml2argv-boot-floppy.xml | 2 + .../qemuxml2argvdata/qemuxml2argv-boot-network.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml | 1 + .../qemuxml2argv-channel-guestfwd.xml | 1 + .../qemuxml2argv-clock-localtime.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-clock-utc.xml | 1 + .../qemuxml2argv-console-compat-chardev.xml | 1 + .../qemuxml2argv-console-compat.xml | 1 + .../qemuxml2argv-disk-cdrom-empty.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml | 1 + .../qemuxml2argv-disk-drive-boot-cdrom.xml | 1 + .../qemuxml2argv-disk-drive-boot-disk.xml | 1 + .../qemuxml2argv-disk-drive-cache-v1-none.xml | 1 + .../qemuxml2argv-disk-drive-cache-v1-wb.xml | 1 + .../qemuxml2argv-disk-drive-cache-v1-wt.xml | 1 + .../qemuxml2argv-disk-drive-cache-v2-none.xml | 1 + .../qemuxml2argv-disk-drive-cache-v2-wb.xml | 1 + .../qemuxml2argv-disk-drive-cache-v2-wt.xml | 1 + .../qemuxml2argv-disk-drive-fat.xml | 1 + .../qemuxml2argv-disk-drive-fmt-qcow.xml | 1 + .../qemuxml2argv-disk-drive-shared.xml | 1 + .../qemuxml2argvdata/qemuxml2argv-disk-floppy.xml | 2 + tests/qemuxml2argvdata/qemuxml2argv-disk-many.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-disk-usb.xml | 1 + .../qemuxml2argvdata/qemuxml2argv-disk-virtio.xml | 1 + .../qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml | 1 + .../qemuxml2argv-floppy-drive-fat.xml | 2 + .../qemuxml2argv-graphics-sdl-fullscreen.xml | 1 + .../qemuxml2argvdata/qemuxml2argv-graphics-sdl.xml | 1 + .../qemuxml2argv-graphics-vnc-sasl.xml | 1 + .../qemuxml2argv-graphics-vnc-tls.xml | 1 + .../qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml | 1 + .../qemuxml2argv-hostdev-pci-address.xml | 1 + .../qemuxml2argv-hostdev-usb-address.xml | 1 + .../qemuxml2argv-hostdev-usb-product.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-hugepages.xml | 1 + .../qemuxml2argv-input-usbmouse.xml | 1 + .../qemuxml2argv-input-usbtablet.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml | 1 + .../qemuxml2argv-machine-aliases1.xml | 1 + .../qemuxml2argv-machine-aliases2.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-migrate.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-minimal.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.xml | 1 + .../qemuxml2argv-misc-no-reboot.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-misc-uuid.xml | 1 + .../qemuxml2argv-net-eth-ifname.xml | 1 + .../qemuxml2argv-net-eth-names.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-net-eth.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-net-user.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-net-virtio.xml | 1 + .../qemuxml2argv-parallel-tcp-chardev.xml | 1 + .../qemuxml2argvdata/qemuxml2argv-parallel-tcp.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-restore-v1.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-restore-v2.xml | 1 + .../qemuxml2argv-serial-dev-chardev.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-serial-dev.xml | 1 + .../qemuxml2argv-serial-file-chardev.xml | 1 + .../qemuxml2argvdata/qemuxml2argv-serial-file.xml | 1 + .../qemuxml2argv-serial-many-chardev.xml | 1 + .../qemuxml2argvdata/qemuxml2argv-serial-many.xml | 1 + .../qemuxml2argv-serial-pty-chardev.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-serial-pty.xml | 1 + .../qemuxml2argv-serial-tcp-chardev.xml | 1 + .../qemuxml2argv-serial-tcp-telnet-chardev.xml | 1 + .../qemuxml2argv-serial-tcp-telnet.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.xml | 1 + .../qemuxml2argv-serial-udp-chardev.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml | 1 + .../qemuxml2argv-serial-unix-chardev.xml | 1 + .../qemuxml2argvdata/qemuxml2argv-serial-unix.xml | 1 + .../qemuxml2argv-serial-vc-chardev.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-serial-vc.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-sound.xml | 1 + tests/qemuxml2argvdata/qemuxml2argv-watchdog.xml | 1 + 80 files changed, 181 insertions(+), 0 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5caf2ca..5edd060 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3539,6 +3539,12 @@ static virDomainDefPtr virDomainDefParseXML(virConnectPtr conn, } VIR_FREE(nodes); + /* Auto-add any further disk controllers implied by declared <disk> + * elements, but not present as <controller> elements + */ + if (virDomainDefAddDiskControllers(def) < 0) + goto error; + /* analysis of the filesystems */ if ((n = virXPathNodeSet(conn, "./devices/filesystem", ctxt, &nodes)) < 0) { virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, @@ -4139,6 +4145,96 @@ cleanup: return obj; } +static int virDomainDefMaybeAddDiskController(virDomainDefPtr def, + int type, + int idx) +{ + int found = 0; + int i; + virDomainControllerDefPtr cont; + + for (i = 0 ; (i < def->ncontrollers) && !found; i++) { + if (def->controllers[i]->type == type && + def->controllers[i]->idx == idx) + found = 1; + } + + if (found) + return 0; + + if (VIR_ALLOC(cont) < 0) { + virReportOOMError(NULL); + return -1; + } + + cont->type = type; + cont->idx = idx; + + if (VIR_REALLOC_N(def->controllers, def->ncontrollers+1) < 0) { + VIR_FREE(cont); + virReportOOMError(NULL); + return -1; + } + def->controllers[def->ncontrollers] = cont; + def->ncontrollers++; + + return 0; +} + +static int virDomainDefAddDiskControllersForType(virDomainDefPtr def, + int controllerType, + int diskBus) +{ + int i; + int maxController = -1; + + for (i = 0 ; i < def->ndisks ; i++) { + if (def->disks[i]->bus != diskBus) + continue; + + if (def->disks[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) + continue; + + if ((int)def->disks[i]->info.addr.drive.controller > maxController) + maxController = def->disks[i]->info.addr.drive.controller; + } + + for (i = 0 ; i <= maxController ; i++) { + if (virDomainDefMaybeAddDiskController(def, controllerType, i) < 0) + return -1; + } + + return 0; +} + + +/* + * Based on the declared <address type=drive> info for any disks, + * add neccessary drive controllers which are not already present + * in the XML. This is for compat with existing apps which will + * not know/care about <controller> info in the XML + */ +int virDomainDefAddDiskControllers(virDomainDefPtr def) +{ + if (virDomainDefAddDiskControllersForType(def, + VIR_DOMAIN_CONTROLLER_TYPE_SCSI, + VIR_DOMAIN_DISK_BUS_SCSI) < 0) + return -1; + + if (virDomainDefAddDiskControllersForType(def, + VIR_DOMAIN_CONTROLLER_TYPE_FDC, + VIR_DOMAIN_DISK_BUS_FDC) < 0) + return -1; + + if (virDomainDefAddDiskControllersForType(def, + VIR_DOMAIN_CONTROLLER_TYPE_IDE, + VIR_DOMAIN_DISK_BUS_IDE) < 0) + return -1; + + return 0; +} + + #endif /* ! PROXY */ /************************************************************************ diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 9f2271c..1831d17 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -776,6 +776,8 @@ virDomainObjPtr virDomainObjParseNode(virConnectPtr conn, xmlDocPtr xml, xmlNodePtr root); +int virDomainDefAddDiskControllers(virDomainDefPtr def); + #endif char *virDomainDefFormat(virConnectPtr conn, virDomainDefPtr def, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index ad57c49..a4a02e7 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -186,6 +186,7 @@ virDomainDeviceAddressClear; virDomainControllerTypeToString; virDomainControllerDefFree; virDomainDeviceAddressTypeToString; +virDomainDefAddDiskControllers; # domain_event.h diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 26baece..ae9147d 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -4449,6 +4449,9 @@ virDomainDefPtr qemuParseCommandLine(virConnectPtr conn, goto no_memory; } + if (virDomainDefAddDiskControllers(def) < 0) + goto error; + return def; no_memory: diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml index 6915145..cf0d3df 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.xml @@ -20,5 +20,6 @@ <readonly/> <address type='drive' controller='0' bus='1' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml index 0b6b084..cf3c5a8 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.xml @@ -24,5 +24,7 @@ <target dev='fda' bus='fdc'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='fdc' index='0'/> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-network.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-network.xml index 4de216e..a28372d 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-network.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-network.xml @@ -19,5 +19,6 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml b/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml index 0501fd4..4af280c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-bootloader.xml @@ -20,5 +20,6 @@ <readonly/> <address type='drive' controller='0' bus='1' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.xml b/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.xml index aeba5be..8963350 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <channel type='pipe'> <source path='/tmp/guestfwd'/> <target type='guestfwd' address='10.0.2.1' port='4600'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime.xml b/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime.xml index 1db0d02..345ae22 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime.xml @@ -19,5 +19,6 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-clock-utc.xml b/tests/qemuxml2argvdata/qemuxml2argv-clock-utc.xml index 9e9153f..533ea59 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-clock-utc.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-utc.xml @@ -19,5 +19,6 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.xml index 1f8f126..df694c7 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='pty'> <target port='0'/> </serial> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-compat.xml b/tests/qemuxml2argvdata/qemuxml2argv-console-compat.xml index 1f8f126..df694c7 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-console-compat.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-console-compat.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='pty'> <target port='0'/> </serial> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml index ff315e1..addbbf1 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.xml @@ -24,5 +24,6 @@ <readonly/> <address type='drive' controller='0' bus='1' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml index 097d3dd..9c10551 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.xml @@ -25,5 +25,6 @@ <readonly/> <address type='drive' controller='0' bus='1' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.xml index 743e996..736e189 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-cdrom.xml @@ -24,5 +24,6 @@ <target dev='hdc' bus='ide'/> <address type='drive' controller='0' bus='1' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.xml index c1d3f4a..c379f31 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-boot-disk.xml @@ -24,5 +24,6 @@ <target dev='hdc' bus='ide'/> <address type='drive' controller='0' bus='1' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.xml index 706b6e2..e689d9c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-none.xml @@ -27,5 +27,6 @@ <readonly/> <address type='drive' controller='0' bus='1' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.xml index 4d3fb0c..be00c4c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wb.xml @@ -27,5 +27,6 @@ <readonly/> <address type='drive' controller='0' bus='1' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.xml index b81f1a4..edf776a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v1-wt.xml @@ -27,5 +27,6 @@ <readonly/> <address type='drive' controller='0' bus='1' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.xml index 706b6e2..e689d9c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-none.xml @@ -27,5 +27,6 @@ <readonly/> <address type='drive' controller='0' bus='1' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.xml index 4d3fb0c..be00c4c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wb.xml @@ -27,5 +27,6 @@ <readonly/> <address type='drive' controller='0' bus='1' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.xml index b81f1a4..edf776a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-v2-wt.xml @@ -27,5 +27,6 @@ <readonly/> <address type='drive' controller='0' bus='1' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.xml index 0a13d19..b2b1b4e 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.xml @@ -21,5 +21,6 @@ <readonly/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.xml index 5c1d456..0b04e69 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fmt-qcow.xml @@ -27,5 +27,6 @@ <readonly/> <address type='drive' controller='0' bus='1' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml index 774decd..47afcd7 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-shared.xml @@ -29,5 +29,6 @@ <readonly/> <address type='drive' controller='0' bus='1' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml index 37d178d..35474be 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.xml @@ -29,5 +29,7 @@ <target dev='fdb' bus='fdc'/> <address type='drive' controller='0' bus='0' unit='1'/> </disk> + <controller type='fdc' index='0'/> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-many.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-many.xml index 6f9b705..467fa5d 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-many.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-many.xml @@ -34,5 +34,6 @@ <target dev='hdd' bus='ide'/> <address type='drive' controller='0' bus='1' unit='1'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-usb.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-usb.xml index 3b86a11..8148626 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-usb.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-usb.xml @@ -23,5 +23,6 @@ <source file='/tmp/usbdisk.img'/> <target dev='sda' bus='usb'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml index c6cf300..2393073 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio.xml @@ -33,5 +33,6 @@ <source file='/tmp/logs.img'/> <target dev='vdb' bus='virtio'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml index 17cc408..0c36457 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-xenvbd.xml @@ -33,5 +33,6 @@ <source file='/tmp/logs.img'/> <target dev='xvdg' bus='xen'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml b/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml index 7bc09fa..6da210d 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml @@ -21,5 +21,7 @@ <readonly/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> + <controller type='fdc' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl-fullscreen.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl-fullscreen.xml index 8508be5..dcecd47 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl-fullscreen.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl-fullscreen.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <input type='mouse' bus='ps2'/> <graphics type='sdl' display=':0.1' xauth='/root/.Xauthority' fullscreen='yes'/> <video> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl.xml index c83587b..f691bfe 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <input type='mouse' bus='ps2'/> <graphics type='sdl' display=':0.1' xauth='/root/.Xauthority'/> <video> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.xml index 15b561f..da0f3c6 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <input type='mouse' bus='ps2'/> <graphics type='vnc' port='5903' autoport='no' listen='127.0.0.1'/> <video> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.xml index 15b561f..da0f3c6 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <input type='mouse' bus='ps2'/> <graphics type='vnc' port='5903' autoport='no' listen='127.0.0.1'/> <video> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml index 15b561f..da0f3c6 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <input type='mouse' bus='ps2'/> <graphics type='vnc' port='5903' autoport='no' listen='127.0.0.1'/> <video> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml index 7c7e548..cb039af 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x06' slot='0x12' function='0x5'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address.xml index 08d78e6..c7d0d91 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <hostdev mode='subsystem' type='usb' managed='no'> <source> <address bus='14' device='6'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-product.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-product.xml index 85a822b..3dc8eeb 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-product.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-product.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <hostdev mode='subsystem' type='usb' managed='no'> <source> <vendor id='0x0204'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hugepages.xml b/tests/qemuxml2argvdata/qemuxml2argv-hugepages.xml index 92f2c47..2e4b75f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hugepages.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-hugepages.xml @@ -22,5 +22,6 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.xml b/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.xml index d036eb4..8603d1b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <input type='mouse' bus='usb'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.xml b/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.xml index 82fd363..6c2a41b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <input type='tablet' bus='usb'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml b/tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml index 9976a56..91dd795 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-input-xen.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <input type='mouse' bus='xen'/> <graphics type='vnc' port='5903' autoport='no' listen='127.0.0.1'/> <video> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.xml b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.xml index eca3a6f..268954d 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases1.xml @@ -19,5 +19,6 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml index b50e409..354b1d5 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-machine-aliases2.xml @@ -19,5 +19,6 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-migrate.xml b/tests/qemuxml2argvdata/qemuxml2argv-migrate.xml index 9e9153f..533ea59 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-migrate.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-migrate.xml @@ -19,5 +19,6 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-minimal.xml b/tests/qemuxml2argvdata/qemuxml2argv-minimal.xml index 78b578b..334a9f9 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-minimal.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-minimal.xml @@ -19,5 +19,6 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.xml b/tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.xml index fe0a00e..474832d 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.xml @@ -22,5 +22,6 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-misc-no-reboot.xml b/tests/qemuxml2argvdata/qemuxml2argv-misc-no-reboot.xml index 2c53078..f75722f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-misc-no-reboot.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-misc-no-reboot.xml @@ -19,5 +19,6 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-misc-uuid.xml b/tests/qemuxml2argvdata/qemuxml2argv-misc-uuid.xml index fe0a00e..474832d 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-misc-uuid.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-misc-uuid.xml @@ -22,5 +22,6 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-eth-ifname.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-eth-ifname.xml index 08aaa35..e24cd99 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-net-eth-ifname.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-eth-ifname.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <interface type='ethernet'> <mac address='00:11:22:33:44:55'/> <script path='/etc/qemu-ifup'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.xml index c52d55b..105d3f6 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <interface type='ethernet'> <mac address='00:11:22:33:44:55'/> <script path='/etc/qemu-ifup'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-eth.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-eth.xml index 9aba26e..27238fc 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-net-eth.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-eth.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <interface type='ethernet'> <mac address='00:11:22:33:44:55'/> <script path='/etc/qemu-ifup'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-user.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-user.xml index 3abda1c..525593d 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-net-user.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-user.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <interface type='user'> <mac address='00:11:22:33:44:55'/> </interface> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio.xml index 4eac686..f8d9acf 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <interface type='user'> <mac address='00:11:22:33:44:55'/> <model type='virtio'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.xml index ab675b6..96a1ca5 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <parallel type='tcp'> <source mode='bind' host='127.0.0.1' service='9999'/> <protocol type='raw'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp.xml b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp.xml index ab675b6..96a1ca5 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <parallel type='tcp'> <source mode='bind' host='127.0.0.1' service='9999'/> <protocol type='raw'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-restore-v1.xml b/tests/qemuxml2argvdata/qemuxml2argv-restore-v1.xml index 9e9153f..533ea59 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-restore-v1.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-restore-v1.xml @@ -19,5 +19,6 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-restore-v2.xml b/tests/qemuxml2argvdata/qemuxml2argv-restore-v2.xml index 9e9153f..533ea59 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-restore-v2.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-restore-v2.xml @@ -19,5 +19,6 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> </devices> </domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.xml index 06c40e8..ae906c2 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='dev'> <source path='/dev/ttyS2'/> <target port='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-dev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev.xml index 06c40e8..ae906c2 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-dev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='dev'> <source path='/dev/ttyS2'/> <target port='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.xml index 7c2cc03..bdc483f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='file'> <source path='/tmp/serial.log'/> <target port='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-file.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-file.xml index 7c2cc03..bdc483f 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-file.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-file.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='file'> <source path='/tmp/serial.log'/> <target port='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.xml index 4021129..38a9498 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='pty'> <target port='0'/> </serial> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-many.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-many.xml index 4021129..38a9498 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-many.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-many.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='pty'> <target port='0'/> </serial> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.xml index 1f8f126..df694c7 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='pty'> <target port='0'/> </serial> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-pty.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty.xml index 1f8f126..df694c7 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-pty.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='pty'> <target port='0'/> </serial> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.xml index 5d14515..a8a3526 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='tcp'> <source mode='connect' host='127.0.0.1' service='9999'/> <protocol type='raw'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.xml index 1f940db..fb80042 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='tcp'> <source mode='bind' host='127.0.0.1' service='9999'/> <protocol type='telnet'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet.xml index 1f940db..fb80042 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='tcp'> <source mode='bind' host='127.0.0.1' service='9999'/> <protocol type='telnet'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.xml index 5d14515..a8a3526 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='tcp'> <source mode='connect' host='127.0.0.1' service='9999'/> <protocol type='raw'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.xml index addf093..01dba47 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='udp'> <source mode='bind' host='127.0.0.1' service='9999'/> <source mode='connect' host='127.0.0.1' service='9998'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml index addf093..01dba47 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='udp'> <source mode='bind' host='127.0.0.1' service='9999'/> <source mode='connect' host='127.0.0.1' service='9998'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.xml index 81884a1..7b90d7b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='unix'> <source mode='connect' path='/tmp/serial.sock'/> <target port='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-unix.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix.xml index 81884a1..7b90d7b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-unix.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='unix'> <source mode='connect' path='/tmp/serial.sock'/> <target port='0'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.xml index 0a1980c..76b3e2a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='vc'> <target port='0'/> </serial> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-vc.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc.xml index 0a1980c..76b3e2a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-vc.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <serial type='vc'> <target port='0'/> </serial> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-sound.xml b/tests/qemuxml2argvdata/qemuxml2argv-sound.xml index 3327c19..85f81ce 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-sound.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-sound.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <sound model='pcspk'/> <sound model='es1370'/> <sound model='sb16'/> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-watchdog.xml b/tests/qemuxml2argvdata/qemuxml2argv-watchdog.xml index 52ff117..07d2c14 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-watchdog.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-watchdog.xml @@ -19,6 +19,7 @@ <target dev='hda' bus='ide'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> <watchdog model='ib700' action='poweroff'/> </devices> </domain> -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:11PM +0000, Daniel P. Berrange wrote:
Existing applications using libvirt are not aware of the disk controller concept. Thus, after parsing the <disk> definitions in the XML, it is neccessary to create <controller> elements to satisfy all requested disks, as per their defined drive addresses
* src/conf/domain_conf.c, src/conf/domain_conf.h, src/libvirt_private.syms: Add virDomainDefAddDiskControllers() method for populating disk controllers, and call it after parsing disk definitions. * src/qemu/qemu_conf.c: Call virDomainDefAddDiskControllers() when doing ARGV -> XML conversion * tests/qemuxml2argvdata/qemuxml2argv*.xml: Add disk controller data to all data files which don't have it already
+/* + * Based on the declared <address type=drive> info for any disks, + * add neccessary drive controllers which are not already present + * in the XML. This is for compat with existing apps which will + * not know/care about <controller> info in the XML + */ +int virDomainDefAddDiskControllers(virDomainDefPtr def) +{ + if (virDomainDefAddDiskControllersForType(def, + VIR_DOMAIN_CONTROLLER_TYPE_SCSI, + VIR_DOMAIN_DISK_BUS_SCSI) < 0) + return -1; + + if (virDomainDefAddDiskControllersForType(def, + VIR_DOMAIN_CONTROLLER_TYPE_FDC, + VIR_DOMAIN_DISK_BUS_FDC) < 0) + return -1; + + if (virDomainDefAddDiskControllersForType(def, + VIR_DOMAIN_CONTROLLER_TYPE_IDE, + VIR_DOMAIN_DISK_BUS_IDE) < 0) + return -1; + + return 0; +}
IIRC a previous patch in the serie disk controler are not sorted, so the order here is just arbitrary, right ?
--- a/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml @@ -21,5 +21,7 @@ <readonly/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> + <controller type='fdc' index='0'/> </devices> </domain>
strange here in the output we get ide before fdc, I would have assume the reverse based on the new function. I hope the order in generated output won't change randomly. Except that remark looks fine, ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Fri, Jan 15, 2010 at 04:24:16PM +0100, Daniel Veillard wrote:
On Fri, Jan 08, 2010 at 05:23:11PM +0000, Daniel P. Berrange wrote:
Existing applications using libvirt are not aware of the disk controller concept. Thus, after parsing the <disk> definitions in the XML, it is neccessary to create <controller> elements to satisfy all requested disks, as per their defined drive addresses
* src/conf/domain_conf.c, src/conf/domain_conf.h, src/libvirt_private.syms: Add virDomainDefAddDiskControllers() method for populating disk controllers, and call it after parsing disk definitions. * src/qemu/qemu_conf.c: Call virDomainDefAddDiskControllers() when doing ARGV -> XML conversion * tests/qemuxml2argvdata/qemuxml2argv*.xml: Add disk controller data to all data files which don't have it already
+/* + * Based on the declared <address type=drive> info for any disks, + * add neccessary drive controllers which are not already present + * in the XML. This is for compat with existing apps which will + * not know/care about <controller> info in the XML + */ +int virDomainDefAddDiskControllers(virDomainDefPtr def) +{ + if (virDomainDefAddDiskControllersForType(def, + VIR_DOMAIN_CONTROLLER_TYPE_SCSI, + VIR_DOMAIN_DISK_BUS_SCSI) < 0) + return -1; + + if (virDomainDefAddDiskControllersForType(def, + VIR_DOMAIN_CONTROLLER_TYPE_FDC, + VIR_DOMAIN_DISK_BUS_FDC) < 0) + return -1; + + if (virDomainDefAddDiskControllersForType(def, + VIR_DOMAIN_CONTROLLER_TYPE_IDE, + VIR_DOMAIN_DISK_BUS_IDE) < 0) + return -1; + + return 0; +}
IIRC a previous patch in the serie disk controler are not sorted, so the order here is just arbitrary, right ?
The code is not sorting controller types, merely controller indexes within a given type. So SCSI / FDC / IDE can appear in any order, but if you add an extra controller of type 'SCSI', it will be inserted in correct position wrt existing SCSI controllers.
--- a/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml @@ -21,5 +21,7 @@ <readonly/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> + <controller type='fdc' index='0'/> </devices> </domain>
strange here in the output we get ide before fdc, I would have assume the reverse based on the new function. I hope the order in generated output won't change randomly.
Except that remark looks fine, ACK,
Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

The PCI device addresses are only valid while the VM is running, since they are auto-assigned by QEMU. After shutdown they must all be cleared. Future QEMU driver enhancement will allow for persistent PCI address assignment * src/conf/domain_conf.h, src/conf/domain_conf.c, src/libvirt_private.syms Add virDomainDefClearPCIAddresses() method for wiping out auto assigned PCI addresses * src/qemu/qemu_driver.c: Clear PCI addresses at VM shutdown --- src/conf/domain_conf.c | 36 ++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 2 ++ src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 2 ++ 4 files changed, 41 insertions(+), 0 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5edd060..ef5dbe9 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -816,6 +816,42 @@ void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info) } +static void virDomainDeviceInfoClearField(virDomainDeviceInfoPtr info) +{ + if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + memset(&info->addr, 0, sizeof(info->addr)); + info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE; + } +} + + +static void virDomainDefClearDeviceInfo(virDomainDefPtr def) +{ + int i; + + for (i = 0; i < def->ndisks ; i++) + virDomainDeviceInfoClearField(&def->disks[i]->info); + for (i = 0; i < def->nnets ; i++) + virDomainDeviceInfoClearField(&def->nets[i]->info); + for (i = 0; i < def->nsounds ; i++) + virDomainDeviceInfoClearField(&def->sounds[i]->info); + for (i = 0; i < def->nhostdevs ; i++) + virDomainDeviceInfoClearField(&def->hostdevs[i]->info); + for (i = 0; i < def->nvideos ; i++) + virDomainDeviceInfoClearField(&def->videos[i]->info); + for (i = 0; i < def->ncontrollers ; i++) + virDomainDeviceInfoClearField(&def->controllers[i]->info); + if (def->watchdog) + virDomainDeviceInfoClearField(&def->watchdog->info); +} + + +void virDomainDefClearPCIAddresses(virDomainDefPtr def) +{ + virDomainDefClearDeviceInfo(def); +} + + /* Generate a string representation of a device address * @param address Device address to stringify */ diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 1831d17..a6f7ab2 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -736,6 +736,8 @@ int virDomainDevicePCIAddressIsValid(virDomainDevicePCIAddressPtr addr); int virDomainDeviceDriveAddressIsValid(virDomainDeviceDriveAddressPtr addr); int virDomainDeviceInfoIsSet(virDomainDeviceInfoPtr info); void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info); +void virDomainDefClearPCIAddresses(virDomainDefPtr def); + void virDomainDefFree(virDomainDefPtr vm); void virDomainObjRef(virDomainObjPtr vm); /* Returns 1 if the object was freed, 0 if more refs exist */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a4a02e7..678d610 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -187,6 +187,7 @@ virDomainControllerTypeToString; virDomainControllerDefFree; virDomainDeviceAddressTypeToString; virDomainDefAddDiskControllers; +virDomainDefClearPCIAddresses; # domain_event.h diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index cd406ec..6a3af61 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3032,6 +3032,8 @@ static void qemudShutdownVMDaemon(virConnectPtr conn, VIR_FREE(vm->def->seclabel.imagelabel); } + virDomainDefClearPCIAddresses(vm->def); + if (qemuDomainSetAllDeviceOwnership(conn, driver, vm->def, 1) < 0) VIR_WARN("Failed to restore all device ownership for %s", vm->def->name); -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:12PM +0000, Daniel P. Berrange wrote:
The PCI device addresses are only valid while the VM is running, since they are auto-assigned by QEMU. After shutdown they must all be cleared. Future QEMU driver enhancement will allow for persistent PCI address assignment
* src/conf/domain_conf.h, src/conf/domain_conf.c, src/libvirt_private.syms Add virDomainDefClearPCIAddresses() method for wiping out auto assigned PCI addresses * src/qemu/qemu_driver.c: Clear PCI addresses at VM shutdown --- src/conf/domain_conf.c | 36 ++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 2 ++ src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 2 ++ 4 files changed, 41 insertions(+), 0 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5edd060..ef5dbe9 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -816,6 +816,42 @@ void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info) }
+static void virDomainDeviceInfoClearField(virDomainDeviceInfoPtr info) +{ + if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + memset(&info->addr, 0, sizeof(info->addr)); + info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE; + } +} + + +static void virDomainDefClearDeviceInfo(virDomainDefPtr def) +{ + int i; + + for (i = 0; i < def->ndisks ; i++) + virDomainDeviceInfoClearField(&def->disks[i]->info); + for (i = 0; i < def->nnets ; i++) + virDomainDeviceInfoClearField(&def->nets[i]->info); + for (i = 0; i < def->nsounds ; i++) + virDomainDeviceInfoClearField(&def->sounds[i]->info); + for (i = 0; i < def->nhostdevs ; i++) + virDomainDeviceInfoClearField(&def->hostdevs[i]->info); + for (i = 0; i < def->nvideos ; i++) + virDomainDeviceInfoClearField(&def->videos[i]->info); + for (i = 0; i < def->ncontrollers ; i++) + virDomainDeviceInfoClearField(&def->controllers[i]->info); + if (def->watchdog) + virDomainDeviceInfoClearField(&def->watchdog->info); +} + + +void virDomainDefClearPCIAddresses(virDomainDefPtr def) +{ + virDomainDefClearDeviceInfo(def); +} + + /* Generate a string representation of a device address * @param address Device address to stringify */ diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 1831d17..a6f7ab2 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -736,6 +736,8 @@ int virDomainDevicePCIAddressIsValid(virDomainDevicePCIAddressPtr addr); int virDomainDeviceDriveAddressIsValid(virDomainDeviceDriveAddressPtr addr); int virDomainDeviceInfoIsSet(virDomainDeviceInfoPtr info); void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info); +void virDomainDefClearPCIAddresses(virDomainDefPtr def); + void virDomainDefFree(virDomainDefPtr vm); void virDomainObjRef(virDomainObjPtr vm); /* Returns 1 if the object was freed, 0 if more refs exist */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a4a02e7..678d610 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -187,6 +187,7 @@ virDomainControllerTypeToString; virDomainControllerDefFree; virDomainDeviceAddressTypeToString; virDomainDefAddDiskControllers; +virDomainDefClearPCIAddresses;
# domain_event.h diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index cd406ec..6a3af61 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3032,6 +3032,8 @@ static void qemudShutdownVMDaemon(virConnectPtr conn, VIR_FREE(vm->def->seclabel.imagelabel); }
+ virDomainDefClearPCIAddresses(vm->def); + if (qemuDomainSetAllDeviceOwnership(conn, driver, vm->def, 1) < 0) VIR_WARN("Failed to restore all device ownership for %s", vm->def->name); -- 1.6.5.2
Hum, I don't see in the patch what's makes the difference between an auto-assigned PCI address and one which might be set by the user. Since it shows up in the XML construct it has to be setable by the user so I'm a bit confused here, ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Fri, Jan 15, 2010 at 05:12:52PM +0100, Daniel Veillard wrote:
On Fri, Jan 08, 2010 at 05:23:12PM +0000, Daniel P. Berrange wrote:
The PCI device addresses are only valid while the VM is running, since they are auto-assigned by QEMU. After shutdown they must all be cleared. Future QEMU driver enhancement will allow for persistent PCI address assignment
* src/conf/domain_conf.h, src/conf/domain_conf.c, src/libvirt_private.syms Add virDomainDefClearPCIAddresses() method for wiping out auto assigned PCI addresses * src/qemu/qemu_driver.c: Clear PCI addresses at VM shutdown --- src/conf/domain_conf.c | 36 ++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 2 ++ src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 2 ++ 4 files changed, 41 insertions(+), 0 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5edd060..ef5dbe9 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -816,6 +816,42 @@ void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info) }
+static void virDomainDeviceInfoClearField(virDomainDeviceInfoPtr info) +{ + if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + memset(&info->addr, 0, sizeof(info->addr)); + info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE; + } +} + + +static void virDomainDefClearDeviceInfo(virDomainDefPtr def) +{ + int i; + + for (i = 0; i < def->ndisks ; i++) + virDomainDeviceInfoClearField(&def->disks[i]->info); + for (i = 0; i < def->nnets ; i++) + virDomainDeviceInfoClearField(&def->nets[i]->info); + for (i = 0; i < def->nsounds ; i++) + virDomainDeviceInfoClearField(&def->sounds[i]->info); + for (i = 0; i < def->nhostdevs ; i++) + virDomainDeviceInfoClearField(&def->hostdevs[i]->info); + for (i = 0; i < def->nvideos ; i++) + virDomainDeviceInfoClearField(&def->videos[i]->info); + for (i = 0; i < def->ncontrollers ; i++) + virDomainDeviceInfoClearField(&def->controllers[i]->info); + if (def->watchdog) + virDomainDeviceInfoClearField(&def->watchdog->info); +} + + +void virDomainDefClearPCIAddresses(virDomainDefPtr def) +{ + virDomainDefClearDeviceInfo(def); +} + + /* Generate a string representation of a device address * @param address Device address to stringify */ diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 1831d17..a6f7ab2 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -736,6 +736,8 @@ int virDomainDevicePCIAddressIsValid(virDomainDevicePCIAddressPtr addr); int virDomainDeviceDriveAddressIsValid(virDomainDeviceDriveAddressPtr addr); int virDomainDeviceInfoIsSet(virDomainDeviceInfoPtr info); void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info); +void virDomainDefClearPCIAddresses(virDomainDefPtr def); + void virDomainDefFree(virDomainDefPtr vm); void virDomainObjRef(virDomainObjPtr vm); /* Returns 1 if the object was freed, 0 if more refs exist */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a4a02e7..678d610 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -187,6 +187,7 @@ virDomainControllerTypeToString; virDomainControllerDefFree; virDomainDeviceAddressTypeToString; virDomainDefAddDiskControllers; +virDomainDefClearPCIAddresses;
# domain_event.h diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index cd406ec..6a3af61 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3032,6 +3032,8 @@ static void qemudShutdownVMDaemon(virConnectPtr conn, VIR_FREE(vm->def->seclabel.imagelabel); }
+ virDomainDefClearPCIAddresses(vm->def); + if (qemuDomainSetAllDeviceOwnership(conn, driver, vm->def, 1) < 0) VIR_WARN("Failed to restore all device ownership for %s", vm->def->name); -- 1.6.5.2
Hum, I don't see in the patch what's makes the difference between an auto-assigned PCI address and one which might be set by the user. Since it shows up in the XML construct it has to be setable by the user so I'm a bit confused here,
This patch series is currently not supporting persistent addresses, so all addresses will be cleared. A later patch will allow persistence when using QEMU >= 0.12 (it isn't possible for older QEMU at all) Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

This patch introduces the support for giving all devices a short, unique name, henceforth known as a 'device alias'. These aliases are not set by the end user, instead being assigned by the hypervisor if it decides it want to support this concept. The QEMU driver sets them whenever using the -device arg syntax and uses them for improved hotplug/hotunplug. it is the intent that other APIs (block / interface stats & device hotplug) be able to accept device alias names in the future. The XML syntax is <alias name="video0"/> This may appear in any type of device that supports device info. * src/conf/domain_conf.c, src/conf/domain_conf.h: Add a 'alias' field to virDomainDeviceInfo struct & parse/format it in XML * src/libvirt_private.syms: Export virDomainDefClearDeviceAliases * src/qemu/qemu_conf.c: Replace use of "nic_name" field with the standard device alias * src/qemu/qemu_driver.c: Clear device aliases at shutdown --- src/conf/domain_conf.c | 110 +++++++++++++++++++++++++++++++--------------- src/conf/domain_conf.h | 4 +- src/libvirt_private.syms | 1 + src/qemu/qemu_conf.c | 8 ++-- src/qemu/qemu_driver.c | 1 + 5 files changed, 82 insertions(+), 42 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index ef5dbe9..7c5abde 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -805,50 +805,61 @@ int virDomainDeviceInfoIsSet(virDomainDeviceInfoPtr info) { if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) return 1; + if (info->alias) + return 1; return 0; } void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info) { + VIR_FREE(info->alias); memset(&info->addr, 0, sizeof(info->addr)); info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE; } -static void virDomainDeviceInfoClearField(virDomainDeviceInfoPtr info) +static void virDomainDeviceInfoClearField(virDomainDeviceInfoPtr info, int alias, int pciaddr) { - if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + if (alias) + VIR_FREE(info->alias); + if (pciaddr && + info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { memset(&info->addr, 0, sizeof(info->addr)); info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE; } } -static void virDomainDefClearDeviceInfo(virDomainDefPtr def) +static void virDomainDefClearDeviceInfo(virDomainDefPtr def, int alias, int pciaddr) { int i; for (i = 0; i < def->ndisks ; i++) - virDomainDeviceInfoClearField(&def->disks[i]->info); + virDomainDeviceInfoClearField(&def->disks[i]->info, alias, pciaddr); for (i = 0; i < def->nnets ; i++) - virDomainDeviceInfoClearField(&def->nets[i]->info); + virDomainDeviceInfoClearField(&def->nets[i]->info, alias, pciaddr); for (i = 0; i < def->nsounds ; i++) - virDomainDeviceInfoClearField(&def->sounds[i]->info); + virDomainDeviceInfoClearField(&def->sounds[i]->info, alias, pciaddr); for (i = 0; i < def->nhostdevs ; i++) - virDomainDeviceInfoClearField(&def->hostdevs[i]->info); + virDomainDeviceInfoClearField(&def->hostdevs[i]->info, alias, pciaddr); for (i = 0; i < def->nvideos ; i++) - virDomainDeviceInfoClearField(&def->videos[i]->info); + virDomainDeviceInfoClearField(&def->videos[i]->info, alias, pciaddr); for (i = 0; i < def->ncontrollers ; i++) - virDomainDeviceInfoClearField(&def->controllers[i]->info); + virDomainDeviceInfoClearField(&def->controllers[i]->info, alias, pciaddr); if (def->watchdog) - virDomainDeviceInfoClearField(&def->watchdog->info); + virDomainDeviceInfoClearField(&def->watchdog->info, alias, pciaddr); } void virDomainDefClearPCIAddresses(virDomainDefPtr def) { - virDomainDefClearDeviceInfo(def); + virDomainDefClearDeviceInfo(def, 0, 1); +} + +void virDomainDefClearDeviceAliases(virDomainDefPtr def) +{ + virDomainDefClearDeviceInfo(def, 1, 0); } @@ -856,7 +867,8 @@ void virDomainDefClearPCIAddresses(virDomainDefPtr def) * @param address Device address to stringify */ static int virDomainDeviceInfoFormat(virBufferPtr buf, - virDomainDeviceInfoPtr info) + virDomainDeviceInfoPtr info, + int flags) { if (!info) { virDomainReportError(NULL, VIR_ERR_INTERNAL_ERROR, "%s", @@ -864,6 +876,11 @@ static int virDomainDeviceInfoFormat(virBufferPtr buf, return -1; } + if (info->alias && + !(flags & VIR_DOMAIN_XML_INACTIVE)) { + virBufferVSprintf(buf, " <alias name='%s'/>\n", info->alias); + } + if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) return 0; @@ -1041,10 +1058,11 @@ static int virDomainDeviceInfoParseXML(virConnectPtr conn, xmlNodePtr node, virDomainDeviceInfoPtr info, - unsigned int flags ATTRIBUTE_UNUSED) + int flags) { xmlNodePtr cur; xmlNodePtr address = NULL; + xmlNodePtr alias = NULL; char *type = NULL; int ret = -1; @@ -1053,14 +1071,21 @@ virDomainDeviceInfoParseXML(virConnectPtr conn, cur = node->children; while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE) { - if (address == NULL && - xmlStrEqual(cur->name, BAD_CAST "address")) { + if (alias == NULL && + !(flags & VIR_DOMAIN_XML_INACTIVE) && + xmlStrEqual(cur->name, BAD_CAST "alias")) { + alias = cur; + } else if (address == NULL && + xmlStrEqual(cur->name, BAD_CAST "address")) { address = cur; } } cur = cur->next; } + if (alias) + info->alias = virXMLPropString(alias, "name"); + if (!address) return 0; @@ -1099,6 +1124,8 @@ virDomainDeviceInfoParseXML(virConnectPtr conn, ret = 0; cleanup: + if (ret == -1) + VIR_FREE(info->alias); VIR_FREE(type); return ret; } @@ -1663,6 +1690,8 @@ virDomainNetDefParseXML(virConnectPtr conn, goto error; } def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + def->info.alias = nic_name; + nic_name = NULL; } else { if (virDomainDeviceInfoParseXML(conn, node, &def->info, flags) < 0) goto error; @@ -1677,9 +1706,8 @@ virDomainNetDefParseXML(virConnectPtr conn, goto error; } - def->nic_name = nic_name; def->hostnet_name = hostnet_name; - nic_name = hostnet_name = NULL; + hostnet_name = NULL; def->vlan = -1; if (vlan && virStrToLong_i(vlan, NULL, 10, &def->vlan) < 0) { @@ -2922,6 +2950,10 @@ virDomainHostdevDefParseXML(virConnectPtr conn, if (virDomainHostdevSubsysPciDefParseXML(conn, cur, def, flags) < 0) goto error; } + } else if (xmlStrEqual(cur->name, BAD_CAST "address")) { + } else { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("unknown node %s"), cur->name); } } cur = cur->next; @@ -4491,7 +4523,8 @@ virDomainLifecycleDefFormat(virConnectPtr conn, static int virDomainDiskDefFormat(virConnectPtr conn, virBufferPtr buf, - virDomainDiskDefPtr def) + virDomainDiskDefPtr def, + int flags) { const char *type = virDomainDiskTypeToString(def->type); const char *device = virDomainDiskDeviceTypeToString(def->device); @@ -4568,7 +4601,7 @@ virDomainDiskDefFormat(virConnectPtr conn, virStorageEncryptionFormat(conn, buf, def->encryption) < 0) return -1; - if (virDomainDeviceInfoFormat(buf, &def->info) < 0) + if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0) return -1; virBufferAddLit(buf, " </disk>\n"); @@ -4579,7 +4612,8 @@ virDomainDiskDefFormat(virConnectPtr conn, static int virDomainControllerDefFormat(virConnectPtr conn, virBufferPtr buf, - virDomainControllerDefPtr def) + virDomainControllerDefPtr def, + int flags) { const char *type = virDomainControllerTypeToString(def->type); @@ -4595,7 +4629,7 @@ virDomainControllerDefFormat(virConnectPtr conn, if (virDomainDeviceInfoIsSet(&def->info)) { virBufferAddLit(buf, ">\n"); - if (virDomainDeviceInfoFormat(buf, &def->info) < 0) + if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0) return -1; virBufferAddLit(buf, " </controller>\n"); } else { @@ -4741,7 +4775,7 @@ virDomainNetDefFormat(virConnectPtr conn, virBufferAddLit(buf, "/>\n"); } - if (virDomainDeviceInfoFormat(buf, &def->info) < 0) + if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0) return -1; virBufferAddLit(buf, " </interface>\n"); @@ -4904,7 +4938,8 @@ cleanup: static int virDomainSoundDefFormat(virConnectPtr conn, virBufferPtr buf, - virDomainSoundDefPtr def) + virDomainSoundDefPtr def, + int flags) { const char *model = virDomainSoundModelTypeToString(def->model); @@ -4919,7 +4954,7 @@ virDomainSoundDefFormat(virConnectPtr conn, if (virDomainDeviceInfoIsSet(&def->info)) { virBufferAddLit(buf, ">\n"); - if (virDomainDeviceInfoFormat(buf, &def->info) < 0) + if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0) return -1; virBufferAddLit(buf, " </sound>\n"); } else { @@ -4933,7 +4968,8 @@ virDomainSoundDefFormat(virConnectPtr conn, static int virDomainWatchdogDefFormat(virConnectPtr conn, virBufferPtr buf, - virDomainWatchdogDefPtr def) + virDomainWatchdogDefPtr def, + int flags) { const char *model = virDomainWatchdogModelTypeToString (def->model); const char *action = virDomainWatchdogActionTypeToString (def->action); @@ -4955,7 +4991,7 @@ virDomainWatchdogDefFormat(virConnectPtr conn, if (virDomainDeviceInfoIsSet(&def->info)) { virBufferAddLit(buf, ">\n"); - if (virDomainDeviceInfoFormat(buf, &def->info) < 0) + if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0) return -1; virBufferAddLit(buf, " </watchdog>\n"); } else { @@ -4981,7 +5017,8 @@ virDomainVideoAccelDefFormat(virBufferPtr buf, static int virDomainVideoDefFormat(virConnectPtr conn, virBufferPtr buf, - virDomainVideoDefPtr def) + virDomainVideoDefPtr def, + int flags) { const char *model = virDomainVideoTypeToString(def->type); @@ -5006,7 +5043,7 @@ virDomainVideoDefFormat(virConnectPtr conn, virBufferAddLit(buf, "/>\n"); } - if (virDomainDeviceInfoFormat(buf, &def->info) < 0) + if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0) return -1; virBufferAddLit(buf, " </video>\n"); @@ -5138,7 +5175,8 @@ virDomainGraphicsDefFormat(virConnectPtr conn, static int virDomainHostdevDefFormat(virConnectPtr conn, virBufferPtr buf, - virDomainHostdevDefPtr def) + virDomainHostdevDefPtr def, + int flags) { const char *mode = virDomainHostdevModeTypeToString(def->mode); const char *type; @@ -5182,7 +5220,7 @@ virDomainHostdevDefFormat(virConnectPtr conn, virBufferAddLit(buf, " </source>\n"); - if (virDomainDeviceInfoFormat(buf, &def->info) < 0) + if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0) return -1; virBufferAddLit(buf, " </hostdev>\n"); @@ -5349,11 +5387,11 @@ char *virDomainDefFormat(virConnectPtr conn, def->emulator); for (n = 0 ; n < def->ndisks ; n++) - if (virDomainDiskDefFormat(conn, &buf, def->disks[n]) < 0) + if (virDomainDiskDefFormat(conn, &buf, def->disks[n], flags) < 0) goto cleanup; for (n = 0 ; n < def->ncontrollers ; n++) - if (virDomainControllerDefFormat(conn, &buf, def->controllers[n]) < 0) + if (virDomainControllerDefFormat(conn, &buf, def->controllers[n], flags) < 0) goto cleanup; for (n = 0 ; n < def->nfss ; n++) @@ -5413,19 +5451,19 @@ char *virDomainDefFormat(virConnectPtr conn, } for (n = 0 ; n < def->nsounds ; n++) - if (virDomainSoundDefFormat(conn, &buf, def->sounds[n]) < 0) + if (virDomainSoundDefFormat(conn, &buf, def->sounds[n], flags) < 0) goto cleanup; for (n = 0 ; n < def->nvideos ; n++) - if (virDomainVideoDefFormat(conn, &buf, def->videos[n]) < 0) + if (virDomainVideoDefFormat(conn, &buf, def->videos[n], flags) < 0) goto cleanup; for (n = 0 ; n < def->nhostdevs ; n++) - if (virDomainHostdevDefFormat(conn, &buf, def->hostdevs[n]) < 0) + if (virDomainHostdevDefFormat(conn, &buf, def->hostdevs[n], flags) < 0) goto cleanup; if (def->watchdog) - virDomainWatchdogDefFormat (conn, &buf, def->watchdog); + virDomainWatchdogDefFormat (conn, &buf, def->watchdog, flags); virBufferAddLit(&buf, " </devices>\n"); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a6f7ab2..87fbba7 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -92,6 +92,7 @@ struct _virDomainDeviceDriveAddress { typedef struct _virDomainDeviceInfo virDomainDeviceInfo; typedef virDomainDeviceInfo *virDomainDeviceInfoPtr; struct _virDomainDeviceInfo { + char *alias; int type; union { virDomainDevicePCIAddress pci; @@ -246,8 +247,6 @@ struct _virDomainNetDef { char *ifname; virDomainDeviceInfo info; /* XXX figure out how to remove this */ - char *nic_name; - /* XXX figure out how to remove this */ char *hostnet_name; /* XXX figure out how to remove this */ int vlan; @@ -737,6 +736,7 @@ int virDomainDeviceDriveAddressIsValid(virDomainDeviceDriveAddressPtr addr); int virDomainDeviceInfoIsSet(virDomainDeviceInfoPtr info); void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info); void virDomainDefClearPCIAddresses(virDomainDefPtr def); +void virDomainDefClearDeviceAliases(virDomainDefPtr def); void virDomainDefFree(virDomainDefPtr vm); void virDomainObjRef(virDomainObjPtr vm); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 678d610..ae0b26c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -188,6 +188,7 @@ virDomainControllerDefFree; virDomainDeviceAddressTypeToString; virDomainDefAddDiskControllers; virDomainDefClearPCIAddresses; +virDomainDefClearDeviceAliases; # domain_event.h diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index ae9147d..6548b4a 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1489,7 +1489,7 @@ qemuAssignNetNames(virDomainDefPtr def, if (def->nets[i] == net) continue; - if (!def->nets[i]->nic_name || !def->nets[i]->hostnet_name) + if (!def->nets[i]->info.alias || !def->nets[i]->hostnet_name) continue; if ((def->nets[i]->model == NULL && net->model == NULL) || @@ -1517,7 +1517,7 @@ qemuAssignNetNames(virDomainDefPtr def, return -1; } - net->nic_name = nic_name; + net->info.alias = nic_name; net->hostnet_name = hostnet_name; return 0; @@ -1714,8 +1714,8 @@ qemuBuildNicStr(virConnectPtr conn, vlan, (net->model ? ",model=" : ""), (net->model ? net->model : ""), - (net->nic_name ? ",name=" : ""), - (net->nic_name ? net->nic_name : "")) < 0) { + (net->info.alias ? ",name=" : ""), + (net->info.alias ? net->info.alias : "")) < 0) { virReportOOMError(conn); return -1; } diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 6a3af61..01dc3c5 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3033,6 +3033,7 @@ static void qemudShutdownVMDaemon(virConnectPtr conn, } virDomainDefClearPCIAddresses(vm->def); + virDomainDefClearDeviceAliases(vm->def); if (qemuDomainSetAllDeviceOwnership(conn, driver, vm->def, 1) < 0) VIR_WARN("Failed to restore all device ownership for %s", -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:13PM +0000, Daniel P. Berrange wrote:
This patch introduces the support for giving all devices a short, unique name, henceforth known as a 'device alias'. These aliases are not set by the end user, instead being assigned by the hypervisor if it decides it want to support this concept.
The QEMU driver sets them whenever using the -device arg syntax and uses them for improved hotplug/hotunplug. it is the intent that other APIs (block / interface stats & device hotplug) be able to accept device alias names in the future.
The XML syntax is
<alias name="video0"/>
This may appear in any type of device that supports device info. [...] -static void virDomainDeviceInfoClearField(virDomainDeviceInfoPtr info) +static void virDomainDeviceInfoClearField(virDomainDeviceInfoPtr info, int alias, int pciaddr) { - if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + if (alias) + VIR_FREE(info->alias); + if (pciaddr && + info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { memset(&info->addr, 0, sizeof(info->addr)); info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE; } }
okay, now this routine really makes sense :-) [...]
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a6f7ab2..87fbba7 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -92,6 +92,7 @@ struct _virDomainDeviceDriveAddress { typedef struct _virDomainDeviceInfo virDomainDeviceInfo; typedef virDomainDeviceInfo *virDomainDeviceInfoPtr; struct _virDomainDeviceInfo { + char *alias; int type; union { virDomainDevicePCIAddress pci; @@ -246,8 +247,6 @@ struct _virDomainNetDef { char *ifname; virDomainDeviceInfo info; /* XXX figure out how to remove this */ - char *nic_name; - /* XXX figure out how to remove this */ char *hostnet_name; /* XXX figure out how to remove this */ int vlan;
and that gives a clear example of use, okay ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Although the serial, parallel, chanel, input & fs devices do not have PCI address info, they can all have device aliases. Thus it neccessary to associate the virDomainDeviceInfo data with them all. * src/conf/domain_conf.c, src/conf/domain_conf.h: Add hooks for parsing / formatting device info for serial, parallel, channel input and fs devices. * docs/schemas/domain.rng: Associate device info with character devices, input & fs device --- docs/schemas/domain.rng | 12 ++++++++ src/conf/domain_conf.c | 67 ++++++++++++++++++++++++++++++++++++++-------- src/conf/domain_conf.h | 4 +++ 3 files changed, 71 insertions(+), 12 deletions(-) diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index a32ce45..f4bef7b 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -600,6 +600,9 @@ </interleave> </group> </choice> + <optional> + <ref name="address"/> + </optional> </element> </define> <define name="filesystemtgt"> @@ -990,6 +993,9 @@ </optional> </element> </optional> + <optional> + <ref name="address"/> + </optional> </interleave> </define> <define name="qemucdevSrcType"> @@ -1119,6 +1125,9 @@ <interleave> <ref name="qemucdevSrcDef"/> <ref name="guestfwdTarget"/> + <optional> + <ref name="address"/> + </optional> </interleave> </element> </define> @@ -1139,6 +1148,9 @@ </choice> </attribute> </optional> + <optional> + <ref name="address"/> + </optional> </element> </define> <define name="hostdev"> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 7c5abde..9c03aab 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -355,6 +355,7 @@ void virDomainInputDefFree(virDomainInputDefPtr def) if (!def) return; + virDomainDeviceInfoClear(&def->info); VIR_FREE(def); } @@ -391,6 +392,7 @@ void virDomainFSDefFree(virDomainFSDefPtr def) VIR_FREE(def->src); VIR_FREE(def->dst); + virDomainDeviceInfoClear(&def->info); VIR_FREE(def); } @@ -474,6 +476,8 @@ void virDomainChrDefFree(virDomainChrDefPtr def) break; } + virDomainDeviceInfoClear(&def->info); + VIR_FREE(def); } @@ -844,11 +848,23 @@ static void virDomainDefClearDeviceInfo(virDomainDefPtr def, int alias, int pcia for (i = 0; i < def->nhostdevs ; i++) virDomainDeviceInfoClearField(&def->hostdevs[i]->info, alias, pciaddr); for (i = 0; i < def->nvideos ; i++) - virDomainDeviceInfoClearField(&def->videos[i]->info, alias, pciaddr); + virDomainDeviceInfoClearField(&def->videos[i]->info, alias, pciaddr); for (i = 0; i < def->ncontrollers ; i++) - virDomainDeviceInfoClearField(&def->controllers[i]->info, alias, pciaddr); + virDomainDeviceInfoClearField(&def->controllers[i]->info, alias, pciaddr); + for (i = 0; i < def->nserials ; i++) + virDomainDeviceInfoClearField(&def->serials[i]->info, alias, pciaddr); + for (i = 0; i < def->nparallels ; i++) + virDomainDeviceInfoClearField(&def->parallels[i]->info, alias, pciaddr); + for (i = 0; i < def->nchannels ; i++) + virDomainDeviceInfoClearField(&def->channels[i]->info, alias, pciaddr); + for (i = 0; i < def->ninputs ; i++) + virDomainDeviceInfoClearField(&def->inputs[i]->info, alias, pciaddr); + for (i = 0; i < def->nfss ; i++) + virDomainDeviceInfoClearField(&def->fss[i]->info, alias, pciaddr); if (def->watchdog) virDomainDeviceInfoClearField(&def->watchdog->info, alias, pciaddr); + if (def->console) + virDomainDeviceInfoClearField(&def->console->info, alias, pciaddr); } @@ -1485,7 +1501,7 @@ cleanup: static virDomainFSDefPtr virDomainFSDefParseXML(virConnectPtr conn, xmlNodePtr node, - int flags ATTRIBUTE_UNUSED) { + int flags) { virDomainFSDefPtr def; xmlNodePtr cur; char *type = NULL; @@ -1549,6 +1565,9 @@ virDomainFSDefParseXML(virConnectPtr conn, def->dst = target; target = NULL; + if (virDomainDeviceInfoParseXML(conn, node, &def->info, flags) < 0) + goto error; + cleanup: VIR_FREE(type); VIR_FREE(target); @@ -1890,7 +1909,7 @@ error: static virDomainChrDefPtr virDomainChrDefParseXML(virConnectPtr conn, xmlNodePtr node, - int flags ATTRIBUTE_UNUSED) { + int flags) { xmlNodePtr cur; char *type = NULL; char *bindHost = NULL; @@ -2184,6 +2203,9 @@ virDomainChrDefParseXML(virConnectPtr conn, break; } + if (virDomainDeviceInfoParseXML(conn, node, &def->info, flags) < 0) + goto error; + cleanup: VIR_FREE(mode); VIR_FREE(protocol); @@ -2210,7 +2232,7 @@ static virDomainInputDefPtr virDomainInputDefParseXML(virConnectPtr conn, const char *ostype, xmlNodePtr node, - int flags ATTRIBUTE_UNUSED) { + int flags) { virDomainInputDefPtr def; char *type = NULL; char *bus = NULL; @@ -2280,6 +2302,9 @@ virDomainInputDefParseXML(virConnectPtr conn, } } + if (virDomainDeviceInfoParseXML(conn, node, &def->info, flags) < 0) + goto error; + cleanup: VIR_FREE(type); VIR_FREE(bus); @@ -4642,7 +4667,8 @@ virDomainControllerDefFormat(virConnectPtr conn, static int virDomainFSDefFormat(virConnectPtr conn, virBufferPtr buf, - virDomainFSDefPtr def) + virDomainFSDefPtr def, + int flags) { const char *type = virDomainFSTypeToString(def->type); @@ -4685,6 +4711,9 @@ virDomainFSDefFormat(virConnectPtr conn, if (def->readonly) virBufferAddLit(buf, " <readonly/>\n"); + if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0) + return -1; + virBufferAddLit(buf, " </filesystem>\n"); return 0; @@ -4926,6 +4955,9 @@ virDomainChrDefFormat(virConnectPtr conn, return -1; } + if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0) + return -1; + virBufferVSprintf(buf, " </%s>\n", elementName); @@ -5054,7 +5086,8 @@ virDomainVideoDefFormat(virConnectPtr conn, static int virDomainInputDefFormat(virConnectPtr conn, virBufferPtr buf, - virDomainInputDefPtr def) + virDomainInputDefPtr def, + int flags) { const char *type = virDomainInputTypeToString(def->type); const char *bus = virDomainInputBusTypeToString(def->bus); @@ -5070,9 +5103,18 @@ virDomainInputDefFormat(virConnectPtr conn, return -1; } - virBufferVSprintf(buf, " <input type='%s' bus='%s'/>\n", + virBufferVSprintf(buf, " <input type='%s' bus='%s'", type, bus); + if (virDomainDeviceInfoIsSet(&def->info)) { + virBufferAddLit(buf, ">\n"); + if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0) + return -1; + virBufferAddLit(buf, " </input>\n"); + } else { + virBufferAddLit(buf, "/>\n"); + } + return 0; } @@ -5395,7 +5437,7 @@ char *virDomainDefFormat(virConnectPtr conn, goto cleanup; for (n = 0 ; n < def->nfss ; n++) - if (virDomainFSDefFormat(conn, &buf, def->fss[n]) < 0) + if (virDomainFSDefFormat(conn, &buf, def->fss[n], flags) < 0) goto cleanup; @@ -5431,7 +5473,7 @@ char *virDomainDefFormat(virConnectPtr conn, for (n = 0 ; n < def->ninputs ; n++) if (def->inputs[n]->bus == VIR_DOMAIN_INPUT_BUS_USB && - virDomainInputDefFormat(conn, &buf, def->inputs[n]) < 0) + virDomainInputDefFormat(conn, &buf, def->inputs[n], flags) < 0) goto cleanup; if (def->ngraphics > 0) { @@ -5439,10 +5481,11 @@ char *virDomainDefFormat(virConnectPtr conn, virDomainInputDef autoInput = { VIR_DOMAIN_INPUT_TYPE_MOUSE, STREQ(def->os.type, "hvm") ? - VIR_DOMAIN_INPUT_BUS_PS2 : VIR_DOMAIN_INPUT_BUS_XEN + VIR_DOMAIN_INPUT_BUS_PS2 : VIR_DOMAIN_INPUT_BUS_XEN, + { .alias = NULL }, }; - if (virDomainInputDefFormat(conn, &buf, &autoInput) < 0) + if (virDomainInputDefFormat(conn, &buf, &autoInput, flags) < 0) goto cleanup; for (n = 0 ; n < def->ngraphics ; n++) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 87fbba7..1413273 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -197,6 +197,7 @@ struct _virDomainFSDef { char *src; char *dst; unsigned int readonly : 1; + virDomainDeviceInfo info; }; @@ -316,6 +317,8 @@ struct _virDomainChrDef { int listen; } nix; } data; + + virDomainDeviceInfo info; }; enum virDomainInputType { @@ -338,6 +341,7 @@ typedef virDomainInputDef *virDomainInputDefPtr; struct _virDomainInputDef { int type; int bus; + virDomainDeviceInfo info; }; enum virDomainSoundModel { -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:14PM +0000, Daniel P. Berrange wrote:
Although the serial, parallel, chanel, input & fs devices do not have PCI address info, they can all have device aliases. Thus it neccessary to associate the virDomainDeviceInfo data with them all.
* src/conf/domain_conf.c, src/conf/domain_conf.h: Add hooks for parsing / formatting device info for serial, parallel, channel input and fs devices. * docs/schemas/domain.rng: Associate device info with character devices, input & fs device --- docs/schemas/domain.rng | 12 ++++++++ src/conf/domain_conf.c | 67 ++++++++++++++++++++++++++++++++++++++-------- src/conf/domain_conf.h | 4 +++ 3 files changed, 71 insertions(+), 12 deletions(-)
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index a32ce45..f4bef7b 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -600,6 +600,9 @@ </interleave> </group> </choice> + <optional> + <ref name="address"/> + </optional> </element> </define> <define name="filesystemtgt"> @@ -990,6 +993,9 @@ </optional> </element> </optional> + <optional> + <ref name="address"/> + </optional> </interleave> </define> <define name="qemucdevSrcType"> @@ -1119,6 +1125,9 @@ <interleave> <ref name="qemucdevSrcDef"/> <ref name="guestfwdTarget"/> + <optional> + <ref name="address"/> + </optional> </interleave> </element> </define> @@ -1139,6 +1148,9 @@ </choice> </attribute> </optional> + <optional> + <ref name="address"/> + </optional> </element> </define> <define name="hostdev">
Hum, unless I'm mistaken this also allow to add a PCI like address on input even if it would be ignored, maybe this should be tightened to just allow the info otherwise looks fine ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Fri, Jan 15, 2010 at 05:26:33PM +0100, Daniel Veillard wrote:
On Fri, Jan 08, 2010 at 05:23:14PM +0000, Daniel P. Berrange wrote:
Although the serial, parallel, chanel, input & fs devices do not have PCI address info, they can all have device aliases. Thus it neccessary to associate the virDomainDeviceInfo data with them all.
* src/conf/domain_conf.c, src/conf/domain_conf.h: Add hooks for parsing / formatting device info for serial, parallel, channel input and fs devices. * docs/schemas/domain.rng: Associate device info with character devices, input & fs device --- docs/schemas/domain.rng | 12 ++++++++ src/conf/domain_conf.c | 67 ++++++++++++++++++++++++++++++++++++++-------- src/conf/domain_conf.h | 4 +++ 3 files changed, 71 insertions(+), 12 deletions(-)
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index a32ce45..f4bef7b 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -600,6 +600,9 @@ </interleave> </group> </choice> + <optional> + <ref name="address"/> + </optional> </element> </define> <define name="filesystemtgt"> @@ -990,6 +993,9 @@ </optional> </element> </optional> + <optional> + <ref name="address"/> + </optional> </interleave> </define> <define name="qemucdevSrcType"> @@ -1119,6 +1125,9 @@ <interleave> <ref name="qemucdevSrcDef"/> <ref name="guestfwdTarget"/> + <optional> + <ref name="address"/> + </optional> </interleave> </element> </define> @@ -1139,6 +1148,9 @@ </choice> </attribute> </optional> + <optional> + <ref name="address"/> + </optional> </element> </define> <define name="hostdev">
Hum, unless I'm mistaken this also allow to add a PCI like address on input even if it would be ignored, maybe this should be tightened to just allow the info
That is correct - it'll allow any of the device info at the parsing stage. Some hypervisors may support PCI based serial, parallel, devices and input devices. Ideally, we should make all the hypervisor drivers check for & reject devices with addressing schemes they don't support but that's alot of work. We might need to thing about exposing a way for hypervisor drivers to register fine grained parser features. So a HV driver could indicate that it only supports devices X, Y & Z with addressing schemes A & B. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

Probe for the new -device flag and if available set the -nodefaults flag, instead of using -net none, -serial none or -parallel none. Other device types will be converted to use -device in later patches. The -nodefaults flag will help avoid unwelcome surprises from future QEMU releases * src/qemu/qemu_conf.c: Probe for -device. Add -nodefaults flag. Remove -net none, -serial none or -parallel none * src/qemu/qemu_conf.h: Define QEMU_CMD_FLAG_DEVICE * tests/qemuhelpdata/qemu-0.12.1: New data file for 0.12.1 QEMU * tests/qemuhelptest.c: Test feature extraction from 0.12.1 QEMU --- src/qemu/qemu_conf.c | 26 ++++- src/qemu/qemu_conf.h | 1 + tests/qemuhelpdata/qemu-0.12.1 | 203 ++++++++++++++++++++++++++++++++++++++++ tests/qemuhelptest.c | 42 ++++++++- 4 files changed, 264 insertions(+), 8 deletions(-) create mode 100644 tests/qemuhelpdata/qemu-0.12.1 diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 6548b4a..3718470 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1115,6 +1115,8 @@ static unsigned int qemudComputeCmdFlags(const char *help, flags |= QEMUD_CMD_FLAG_CHARDEV; if (strstr(help, "-balloon")) flags |= QEMUD_CMD_FLAG_BALLOON; + if (strstr(help, "-device")) + flags |= QEMUD_CMD_FLAG_DEVICE; if (version >= 9000) flags |= QEMUD_CMD_FLAG_VNC_COLON; @@ -2308,6 +2310,9 @@ int qemudBuildCommandLine(virConnectPtr conn, if (!def->graphics) ADD_ARG_LIT("-nographic"); + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) + ADD_ARG_LIT("-nodefaults"); + if (monitor_chr) { virBuffer buf = VIR_BUFFER_INITIALIZER; @@ -2530,8 +2535,11 @@ int qemudBuildCommandLine(virConnectPtr conn, } if (!def->nnets) { - ADD_ARG_LIT("-net"); - ADD_ARG_LIT("none"); + /* If we have -device, then we set -nodefault already */ + if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) { + ADD_ARG_LIT("-net"); + ADD_ARG_LIT("none"); + } } else { for (i = 0 ; i < def->nnets ; i++) { virDomainNetDefPtr net = def->nets[i]; @@ -2590,8 +2598,11 @@ int qemudBuildCommandLine(virConnectPtr conn, } if (!def->nserials) { - ADD_ARG_LIT("-serial"); - ADD_ARG_LIT("none"); + /* If we have -device, then we set -nodefault already */ + if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) { + ADD_ARG_LIT("-serial"); + ADD_ARG_LIT("none"); + } } else { for (i = 0 ; i < def->nserials ; i++) { virBuffer buf = VIR_BUFFER_INITIALIZER; @@ -2637,8 +2648,11 @@ int qemudBuildCommandLine(virConnectPtr conn, } if (!def->nparallels) { - ADD_ARG_LIT("-parallel"); - ADD_ARG_LIT("none"); + /* If we have -device, then we set -nodefault already */ + if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) { + ADD_ARG_LIT("-parallel"); + ADD_ARG_LIT("none"); + } } else { for (i = 0 ; i < def->nparallels ; i++) { virBuffer buf = VIR_BUFFER_INITIALIZER; diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 3dbe1c8..174d397 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -78,6 +78,7 @@ enum qemud_cmd_flags { QEMUD_CMD_FLAG_ENABLE_KVM = (1 << 23), /* Is the -enable-kvm flag available to "enable KVM full virtualization support" */ QEMUD_CMD_FLAG_MONITOR_JSON = (1 << 24), /* JSON mode for monitor */ QEMUD_CMD_FLAG_BALLOON = (1 << 25), /* -balloon available */ + QEMUD_CMD_FLAG_DEVICE = (1 << 26), /* Is the new -chardev arg available */ }; /* Main driver state */ diff --git a/tests/qemuhelpdata/qemu-0.12.1 b/tests/qemuhelpdata/qemu-0.12.1 new file mode 100644 index 0000000..748625b --- /dev/null +++ b/tests/qemuhelpdata/qemu-0.12.1 @@ -0,0 +1,203 @@ +QEMU PC emulator version 0.12.1, Copyright (c) 2003-2008 Fabrice Bellard +usage: qemu [options] [disk_image] + +'disk_image' is a raw hard image image for IDE hard disk 0 + +Standard options: +-h or -help display this help and exit +-version display version information and exit +-M machine select emulated machine (-M ? for list) +-cpu cpu select CPU (-cpu ? for list) +-smp n[,maxcpus=cpus][,cores=cores][,threads=threads][,sockets=sockets] + set the number of CPUs to 'n' [default=1] + maxcpus= maximum number of total cpus, including + offline CPUs for hotplug etc. + cores= number of CPU cores on one socket + threads= number of threads on one CPU core + sockets= number of discrete sockets in the system +-numa node[,mem=size][,cpus=cpu[-cpu]][,nodeid=node] +-fda/-fdb file use 'file' as floppy disk 0/1 image +-hda/-hdb file use 'file' as IDE hard disk 0/1 image +-hdc/-hdd file use 'file' as IDE hard disk 2/3 image +-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master) +-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i] + [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off] + [,cache=writethrough|writeback|none][,format=f][,serial=s] + [,addr=A][,id=name][,aio=threads|native] + use 'file' as a drive image +-set group.id.arg=value + set <arg> parameter for item <id> of type <group> + i.e. -set drive.$id.file=/path/to/image +-global driver.property=value + set a global default for a driver property +-mtdblock file use 'file' as on-board Flash memory image +-sd file use 'file' as SecureDigital card image +-pflash file use 'file' as a parallel flash image +-boot [order=drives][,once=drives][,menu=on|off] + 'drives': floppy (a), hard disk (c), CD-ROM (d), network (n) +-snapshot write to temporary files instead of disk image files +-m megs set virtual RAM size to megs MB [default=128] +-k language use keyboard layout (for example 'fr' for French) +-audio-help print list of audio drivers and their options +-soundhw c1,... enable audio support + and only specified sound cards (comma separated list) + use -soundhw ? to get the list of supported cards + use -soundhw all to enable all of them +-usb enable the USB driver (will be the default soon) +-usbdevice name add the host or guest USB device 'name' +-device driver[,options] add device +-name string1[,process=string2] set the name of the guest + string1 sets the window title and string2 the process name (on Linux) +-uuid %08x-%04x-%04x-%04x-%012x + specify machine UUID + +Display options: +-nographic disable graphical output and redirect serial I/Os to console +-curses use a curses/ncurses interface instead of SDL +-no-frame open SDL window without a frame and window decorations +-alt-grab use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt) +-ctrl-grab use Right-Ctrl to grab mouse (instead of Ctrl-Alt) +-no-quit disable SDL window close capability +-sdl enable SDL +-portrait rotate graphical output 90 deg left (only PXA LCD) +-vga [std|cirrus|vmware|xenfb|none] + select video card type +-full-screen start in full screen +-vnc display start a VNC server on display + +1 target only: +-win2k-hack use it when installing Windows 2000 to avoid a disk full bug +-no-fd-bootchk disable boot signature checking for floppy disks +-no-acpi disable ACPI +-no-hpet disable HPET +-balloon none disable balloon device +-balloon virtio[,addr=str] + enable virtio balloon device (default) +-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=n][,data=file1[:file2]...] + ACPI table description +-smbios file=binary + Load SMBIOS entry from binary file +-smbios type=0[,vendor=str][,version=str][,date=str][,release=%d.%d] + Specify SMBIOS type 0 fields +-smbios type=1[,manufacturer=str][,product=str][,version=str][,serial=str] + [,uuid=uuid][,sku=str][,family=str] + Specify SMBIOS type 1 fields + +Network options: +-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v] + create a new Network Interface Card and connect it to VLAN 'n' +-net user[,vlan=n][,name=str][,net=addr[/mask]][,host=addr][,restrict=y|n] + [,hostname=host][,dhcpstart=addr][,dns=addr][,tftp=dir][,bootfile=f] + [,hostfwd=rule][,guestfwd=rule][,smb=dir[,smbserver=addr]] + connect the user mode network stack to VLAN 'n', configure its + DHCP server and enabled optional services +-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,sndbuf=nbytes][,vnet_hdr=on|off] + connect the host TAP network interface to VLAN 'n' and use the + network scripts 'file' (default=/etc/qemu-ifup) + and 'dfile' (default=/etc/qemu-ifdown); + use '[down]script=no' to disable script execution; + use 'fd=h' to connect to an already opened TAP interface + use 'sndbuf=nbytes' to limit the size of the send buffer; the + default of 'sndbuf=1048576' can be disabled using 'sndbuf=0' + use vnet_hdr=off to avoid enabling the IFF_VNET_HDR tap flag; use + vnet_hdr=on to make the lack of IFF_VNET_HDR support an error condition +-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port] + connect the vlan 'n' to another VLAN using a socket connection +-net socket[,vlan=n][,name=str][,fd=h][,mcast=maddr:port] + connect the vlan 'n' to multicast maddr and port +-net dump[,vlan=n][,file=f][,len=n] + dump traffic on vlan 'n' to file 'f' (max n bytes per packet) +-net none use it alone to have zero network devices; if no -net option + is provided, the default is '-net nic -net user' +-netdev [user|tap|socket],id=str[,option][,option][,...] + +Character device options: +-chardev null,id=id +-chardev socket,id=id[,host=host],port=host[,to=to][,ipv4][,ipv6][,nodelay] + [,server][,nowait][,telnet] (tcp) +-chardev socket,id=id,path=path[,server][,nowait][,telnet] (unix) +-chardev udp,id=id[,host=host],port=port[,localaddr=localaddr] + [,localport=localport][,ipv4][,ipv6] +-chardev msmouse,id=id +-chardev vc,id=id[[,width=width][,height=height]][[,cols=cols][,rows=rows]] +-chardev file,id=id,path=path +-chardev pipe,id=id,path=path +-chardev pty,id=id +-chardev stdio,id=id +-chardev tty,id=id,path=path +-chardev parport,id=id,path=path + +Bluetooth(R) options: +-bt hci,null dumb bluetooth HCI - doesn't respond to commands +-bt hci,host[:id] + use host's HCI with the given name +-bt hci[,vlan=n] + emulate a standard HCI in virtual scatternet 'n' +-bt vhci[,vlan=n] + add host computer to virtual scatternet 'n' using VHCI +-bt device:dev[,vlan=n] + emulate a bluetooth device 'dev' in scatternet 'n' + +Linux/Multiboot boot specific: +-kernel bzImage use 'bzImage' as kernel image +-append cmdline use 'cmdline' as kernel command line +-initrd file use 'file' as initial ram disk + +Debug/Expert options: +-serial dev redirect the serial port to char device 'dev' +-parallel dev redirect the parallel port to char device 'dev' +-monitor dev redirect the monitor to char device 'dev' +-qmp dev like -monitor but opens in 'control' mode. +-mon chardev=[name][,mode=readline|control][,default] +-pidfile file write PID to 'file' +-singlestep always run in singlestep mode +-S freeze CPU at startup (use 'c' to start execution) +-gdb dev wait for gdb connection on 'dev' +-s shorthand for -gdb tcp::1234 +-d item1,... output log to /tmp/qemu.log (use -d ? for a list of log items) +-hdachs c,h,s[,t] + force hard disk 0 physical geometry and the optional BIOS + translation (t=none or lba) (usually qemu can guess them) +-L path set the directory for the BIOS, VGA BIOS and keymaps +-bios file set the filename for the BIOS +-enable-kvm enable KVM full virtualization support +-xen-domid id specify xen guest domain id +-xen-create create domain using xen hypercalls, bypassing xend + warning: should not be used when xend is in use +-xen-attach attach to existing xen domain + xend will use this when starting qemu +-no-reboot exit instead of rebooting +-no-shutdown stop before shutdown +-loadvm [tag|id] + start right away with a saved state (loadvm in monitor) +-daemonize daemonize QEMU after initializing +-option-rom rom load a file, rom, into the option ROM space +-clock force the use of the given methods for timer alarm. + To see what timers are available use -clock ? +-rtc [base=utc|localtime|date][,clock=host|vm][,driftfix=none|slew] + set the RTC base and clock, enable drift fix for clock ticks +-icount [N|auto] + enable virtual instruction counter with 2^N clock ticks per + instruction +-watchdog i6300esb|ib700 + enable virtual hardware watchdog [default=none] +-watchdog-action reset|shutdown|poweroff|pause|debug|none + action when watchdog fires [default=reset] +-echr chr set terminal escape character instead of ctrl-a +-virtioconsole c + set virtio console +-show-cursor show cursor +-tb-size n set TB size +-incoming p prepare for incoming migration, listen on port p +-nodefaults don't create default devices. +-chroot dir Chroot to dir just before starting the VM. +-runas user Change to user id user just before starting the VM. +-readconfig <file> +-writeconfig <file> + read/write config file +During emulation, the following keys are useful: +ctrl-alt-f toggle full screen +ctrl-alt-n switch to virtual console 'n' +ctrl-alt toggle mouse and keyboard grab + +When using -nographic, press 'ctrl-a h' to get some help. diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c index 0a78b05..c2d7942 100644 --- a/tests/qemuhelptest.c +++ b/tests/qemuhelptest.c @@ -21,6 +21,20 @@ struct testInfo { static char *progname; static char *abs_srcdir; +static void printMismatchedFlags(int got, int expect) +{ + int i; + + for (i = 0 ; i < (sizeof(got)*8) ; i++) { + int gotFlag = (got & (1 << i)); + int expectFlag = (expect & (1 << i)); + if (gotFlag && !expectFlag) + fprintf(stderr, "Extra flag %i\n", i); + if (!gotFlag && expectFlag) + fprintf(stderr, "Missing flag %i\n", i); + } +} + static int testHelpStrParsing(const void *data) { const struct testInfo *info = data; @@ -40,6 +54,10 @@ static int testHelpStrParsing(const void *data) if (flags != info->flags) { fprintf(stderr, "Computed flags do not match: got 0x%x, expected 0x%x\n", flags, info->flags); + + if (getenv("VIR_TEST_DEBUG")) + printMismatchedFlags(flags, info->flags); + return -1; } @@ -55,9 +73,9 @@ static int testHelpStrParsing(const void *data) return -1; } - if (kvm_version != kvm_version) { + if (kvm_version != info->kvm_version) { fprintf(stderr, "Parsed KVM versions do not match: got %u, expected %u\n", - version, kvm_version); + kvm_version, info->kvm_version); return -1; } @@ -182,6 +200,26 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_ENABLE_KVM | QEMUD_CMD_FLAG_BALLOON, 10092, 1, 0); + DO_TEST("qemu-0.12.1", + QEMUD_CMD_FLAG_VNC_COLON | + QEMUD_CMD_FLAG_NO_REBOOT | + QEMUD_CMD_FLAG_DRIVE | + QEMUD_CMD_FLAG_NAME | + QEMUD_CMD_FLAG_UUID | + QEMUD_CMD_FLAG_MIGRATE_QEMU_TCP | + QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC | + QEMUD_CMD_FLAG_DRIVE_CACHE_V2 | + QEMUD_CMD_FLAG_DRIVE_FORMAT | + QEMUD_CMD_FLAG_DRIVE_SERIAL | + QEMUD_CMD_FLAG_VGA | + QEMUD_CMD_FLAG_0_10 | + QEMUD_CMD_FLAG_ENABLE_KVM | + QEMUD_CMD_FLAG_XEN_DOMID | + QEMUD_CMD_FLAG_MIGRATE_QEMU_UNIX | + QEMUD_CMD_FLAG_CHARDEV | + QEMUD_CMD_FLAG_BALLOON | + QEMUD_CMD_FLAG_DEVICE, + 12001, 0, 0); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:15PM +0000, Daniel P. Berrange wrote:
Probe for the new -device flag and if available set the -nodefaults flag, instead of using -net none, -serial none or -parallel none. Other device types will be converted to use -device in later patches. The -nodefaults flag will help avoid unwelcome surprises from future QEMU releases
* src/qemu/qemu_conf.c: Probe for -device. Add -nodefaults flag. Remove -net none, -serial none or -parallel none * src/qemu/qemu_conf.h: Define QEMU_CMD_FLAG_DEVICE * tests/qemuhelpdata/qemu-0.12.1: New data file for 0.12.1 QEMU * tests/qemuhelptest.c: Test feature extraction from 0.12.1 QEMU [...] @@ -1115,6 +1115,8 @@ static unsigned int qemudComputeCmdFlags(const char *help, flags |= QEMUD_CMD_FLAG_CHARDEV; if (strstr(help, "-balloon")) flags |= QEMUD_CMD_FLAG_BALLOON; + if (strstr(help, "-device")) + flags |= QEMUD_CMD_FLAG_DEVICE;
[...]
--- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -78,6 +78,7 @@ enum qemud_cmd_flags { QEMUD_CMD_FLAG_ENABLE_KVM = (1 << 23), /* Is the -enable-kvm flag available to "enable KVM full virtualization support" */ QEMUD_CMD_FLAG_MONITOR_JSON = (1 << 24), /* JSON mode for monitor */ QEMUD_CMD_FLAG_BALLOON = (1 << 25), /* -balloon available */ + QEMUD_CMD_FLAG_DEVICE = (1 << 26), /* Is the new -chardev arg available */ };
comment error, it's -device arg, not -chardev which is tested there
--- a/tests/qemuhelptest.c +++ b/tests/qemuhelptest.c @@ -21,6 +21,20 @@ struct testInfo { static char *progname; static char *abs_srcdir;
+static void printMismatchedFlags(int got, int expect) +{ + int i; + + for (i = 0 ; i < (sizeof(got)*8) ; i++) { + int gotFlag = (got & (1 << i)); + int expectFlag = (expect & (1 << i)); + if (gotFlag && !expectFlag) + fprintf(stderr, "Extra flag %i\n", i); + if (!gotFlag && expectFlag) + fprintf(stderr, "Missing flag %i\n", i); + } +} + static int testHelpStrParsing(const void *data) { const struct testInfo *info = data; @@ -40,6 +54,10 @@ static int testHelpStrParsing(const void *data) if (flags != info->flags) { fprintf(stderr, "Computed flags do not match: got 0x%x, expected 0x%x\n", flags, info->flags); + + if (getenv("VIR_TEST_DEBUG")) + printMismatchedFlags(flags, info->flags); + return -1; }
Ah, nice improvement ! ACK, but comment need fix Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

When starting a guest, give every device a unique alias. This will be used for the 'id' parameter in -device args in later patches. It can also be used to uniquely identify devices in the monitor For old QEMU without -device, assign disk names based on QEMU's historical naming scheme. * src/qemu/qemu_conf.c: Assign unique device aliases * src/qemu/qemu_driver.c: Remove obsolete qemudDiskDeviceName and use the device alias in eject & blockstats commands --- src/qemu/qemu_conf.c | 173 ++++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_driver.c | 104 ++++++----------------------- 2 files changed, 195 insertions(+), 82 deletions(-) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 3718470..5dcd50f 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1460,6 +1460,173 @@ cleanup: return tapfd; } + +static int +qemuAssignDeviceAliases(virDomainDefPtr def) +{ + int i; + + for (i = 0; i < def->ndisks ; i++) { + const char *prefix = virDomainDiskBusTypeToString(def->disks[i]->bus); + if (def->disks[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE) { + if (virAsprintf(&def->disks[i]->info.alias, "%s%d-%d-%d", prefix, + def->disks[i]->info.addr.drive.controller, + def->disks[i]->info.addr.drive.bus, + def->disks[i]->info.addr.drive.unit) < 0) + goto no_memory; + } else { + int idx = virDiskNameToIndex(def->disks[i]->dst); + if (virAsprintf(&def->disks[i]->info.alias, "%s-disk%d", prefix, idx) < 0) + goto no_memory; + } + } + for (i = 0; i < def->nnets ; i++) { + if (def->nets[i]->model) { + if (virAsprintf(&def->nets[i]->info.alias, "%s-nic%d", def->nets[i]->model, i) < 0) + goto no_memory; + } else { + if (virAsprintf(&def->nets[i]->info.alias, "nic%d", i) < 0) + goto no_memory; + } + } + + for (i = 0; i < def->nsounds ; i++) { + if (virAsprintf(&def->sounds[i]->info.alias, "sound%d", i) < 0) + goto no_memory; + } + for (i = 0; i < def->nhostdevs ; i++) { + if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { + const char *prefix = virDomainHostdevSubsysTypeToString + (def->hostdevs[i]->source.subsys.type); + if (virAsprintf(&def->hostdevs[i]->info.alias, "host%s%d", prefix, i) < 0) + goto no_memory; + } else { + if (virAsprintf(&def->hostdevs[i]->info.alias, "host%d",i) < 0) + goto no_memory; + } + } + for (i = 0; i < def->nvideos ; i++) { + if (virAsprintf(&def->videos[i]->info.alias, "video%d", i) < 0) + goto no_memory; + } + for (i = 0; i < def->ncontrollers ; i++) { + const char *prefix = virDomainControllerTypeToString(def->controllers[i]->type); + if (virAsprintf(&def->controllers[i]->info.alias, "%s%d", prefix, i) < 0) + goto no_memory; + } + for (i = 0; i < def->ninputs ; i++) { + if (virAsprintf(&def->inputs[i]->info.alias, "input%d", i) < 0) + goto no_memory; + } + for (i = 0; i < def->nparallels ; i++) { + if (virAsprintf(&def->parallels[i]->info.alias, "parallel%d", i) < 0) + goto no_memory; + } + for (i = 0; i < def->nserials ; i++) { + if (virAsprintf(&def->serials[i]->info.alias, "serial%d", i) < 0) + goto no_memory; + } + for (i = 0; i < def->nchannels ; i++) { + if (virAsprintf(&def->channels[i]->info.alias, "channel%d", i) < 0) + goto no_memory; + } + if (def->watchdog) { + if (virAsprintf(&def->watchdog->info.alias, "watchdog%d", 0) < 0) + goto no_memory; + } + + return 0; + + no_memory: + virReportOOMError(NULL); + return -1; +} + + +static char *qemuDiskLegacyName(const virDomainDiskDefPtr disk) +{ + char *devname; + + if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM && + STREQ(disk->dst, "hdc")) + devname = strdup("cdrom"); + else + devname = strdup(disk->dst); + + if (!devname) + virReportOOMError(NULL); + + return NULL; +} + +/* Return the -drive QEMU disk name for use in monitor commands */ +static char *qemuDiskDriveName(const virDomainDiskDefPtr disk) +{ + int busid, devid; + int ret; + char *devname; + + if (virDiskNameToBusDeviceIndex(disk, &busid, &devid) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("cannot convert disk '%s' to bus/device index"), + disk->dst); + return NULL; + } + + switch (disk->bus) { + case VIR_DOMAIN_DISK_BUS_IDE: + if (disk->device== VIR_DOMAIN_DISK_DEVICE_DISK) + ret = virAsprintf(&devname, "ide%d-hd%d", busid, devid); + else + ret = virAsprintf(&devname, "ide%d-cd%d", busid, devid); + break; + case VIR_DOMAIN_DISK_BUS_SCSI: + if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) + ret = virAsprintf(&devname, "scsi%d-hd%d", busid, devid); + else + ret = virAsprintf(&devname, "scsi%d-cd%d", busid, devid); + break; + case VIR_DOMAIN_DISK_BUS_FDC: + ret = virAsprintf(&devname, "floppy%d", devid); + break; + case VIR_DOMAIN_DISK_BUS_VIRTIO: + ret = virAsprintf(&devname, "virtio%d", devid); + break; + default: + qemudReportError(NULL, NULL, NULL, VIR_ERR_NO_SUPPORT, + _("Unsupported disk name mapping for bus '%s'"), + virDomainDiskBusTypeToString(disk->bus)); + return NULL; + } + + if (ret == -1) { + virReportOOMError(NULL); + return NULL; + } + + return devname; +} + +static int +qemuAssignDiskAliases(virDomainDefPtr def, int qemuCmdFlags) +{ + int i; + + for (i = 0 ; i < def->ndisks ; i++) { + if (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE) + def->disks[i]->info.alias = + qemuDiskDriveName(def->disks[i]); + else + def->disks[i]->info.alias = + qemuDiskLegacyName(def->disks[i]); + + if (!def->disks[i]->info.alias) + return -1; + } + return 0; +} + + static const char * qemuNetTypeToHostNet(int type) { @@ -2077,6 +2244,11 @@ int qemudBuildCommandLine(virConnectPtr conn, uname_normalize(&ut); + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) + qemuAssignDeviceAliases(def); + else + qemuAssignDiskAliases(def, qemuCmdFlags); + virUUIDFormat(def->uuid, uuid); /* Migration is very annoying due to wildly varying syntax & capabilities @@ -2550,6 +2722,7 @@ int qemudBuildCommandLine(virConnectPtr conn, ADD_ARG_SPACE; if ((qemuCmdFlags & QEMUD_CMD_FLAG_NET_NAME) && + !(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) && qemuAssignNetNames(def, net) < 0) goto no_memory; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 01dc3c5..37b2730 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -5305,63 +5305,13 @@ cleanup: return ret; } -/* Return the disks name for use in monitor commands */ -static char *qemudDiskDeviceName(const virConnectPtr conn, - const virDomainDiskDefPtr disk) { - - int busid, devid; - int ret; - char *devname; - - if (virDiskNameToBusDeviceIndex(disk, &busid, &devid) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("cannot convert disk '%s' to bus/device index"), - disk->dst); - return NULL; - } - - switch (disk->bus) { - case VIR_DOMAIN_DISK_BUS_IDE: - if (disk->device== VIR_DOMAIN_DISK_DEVICE_DISK) - ret = virAsprintf(&devname, "ide%d-hd%d", busid, devid); - else - ret = virAsprintf(&devname, "ide%d-cd%d", busid, devid); - break; - case VIR_DOMAIN_DISK_BUS_SCSI: - if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) - ret = virAsprintf(&devname, "scsi%d-hd%d", busid, devid); - else - ret = virAsprintf(&devname, "scsi%d-cd%d", busid, devid); - break; - case VIR_DOMAIN_DISK_BUS_FDC: - ret = virAsprintf(&devname, "floppy%d", devid); - break; - case VIR_DOMAIN_DISK_BUS_VIRTIO: - ret = virAsprintf(&devname, "virtio%d", devid); - break; - default: - qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT, - _("Unsupported disk name mapping for bus '%s'"), - virDomainDiskBusTypeToString(disk->bus)); - return NULL; - } - - if (ret == -1) { - virReportOOMError(conn); - return NULL; - } - - return devname; -} static int qemudDomainChangeEjectableMedia(virConnectPtr conn, struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - unsigned int qemuCmdFlags) + virDomainDeviceDefPtr dev) { virDomainDiskDefPtr origdisk = NULL, newdisk; - char *devname = NULL; int i; int ret; @@ -5383,29 +5333,18 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn, return -1; } - if (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE) { - if (!(devname = qemudDiskDeviceName(conn, newdisk))) - return -1; - } else { - /* Back compat for no -drive option */ - if (newdisk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) - devname = strdup(newdisk->dst); - else if (newdisk->device == VIR_DOMAIN_DISK_DEVICE_CDROM && - STREQ(newdisk->dst, "hdc")) - devname = strdup("cdrom"); - else { - qemudReportError(conn, dom, NULL, VIR_ERR_INTERNAL_ERROR, - _("Emulator version does not support removable " - "media for device '%s' and target '%s'"), - virDomainDiskDeviceTypeToString(newdisk->device), - newdisk->dst); - return -1; - } + if (!origdisk->info.alias) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("missing disk device alias name for %s"), origdisk->dst); + return -1; + } - if (!devname) { - virReportOOMError(conn); - return -1; - } + if (origdisk->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY && + origdisk->device != VIR_DOMAIN_DISK_DEVICE_CDROM) { + qemudReportError(conn, dom, NULL, VIR_ERR_INTERNAL_ERROR, + _("Removable media not supported for %s device"), + virDomainDiskDeviceTypeToString(newdisk->device)); + return -1; } qemuDomainObjPrivatePtr priv = vm->privateData; @@ -5418,9 +5357,11 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn, else if (origdisk->driverType) format = origdisk->driverType; } - ret = qemuMonitorChangeMedia(priv->mon, devname, newdisk->src, format); + ret = qemuMonitorChangeMedia(priv->mon, + origdisk->info.alias, + newdisk->src, format); } else { - ret = qemuMonitorEjectMedia(priv->mon, devname); + ret = qemuMonitorEjectMedia(priv->mon, origdisk->info.alias); } qemuDomainObjExitMonitorWithDriver(driver, vm); @@ -5430,7 +5371,6 @@ static int qemudDomainChangeEjectableMedia(virConnectPtr conn, newdisk->src = NULL; origdisk->type = newdisk->type; } - VIR_FREE(devname); return ret; } @@ -5976,7 +5916,7 @@ static int qemudDomainAttachDevice(virDomainPtr dom, if (qemuDomainSetDeviceOwnership(dom->conn, driver, dev, 0) < 0) goto endjob; - ret = qemudDomainChangeEjectableMedia(dom->conn, driver, vm, dev, qemuCmdFlags); + ret = qemudDomainChangeEjectableMedia(dom->conn, driver, vm, dev); break; case VIR_DOMAIN_DISK_DEVICE_DISK: @@ -6712,7 +6652,6 @@ qemudDomainBlockStats (virDomainPtr dom, struct _virDomainBlockStats *stats) { struct qemud_driver *driver = dom->conn->privateData; - const char *qemu_dev_name = NULL; int i, ret = -1; virDomainObjPtr vm; virDomainDiskDefPtr disk = NULL; @@ -6750,14 +6689,16 @@ qemudDomainBlockStats (virDomainPtr dom, goto endjob; } - qemu_dev_name = qemudDiskDeviceName(dom->conn, disk); - if (!qemu_dev_name) + if (!disk->info.alias) { + qemudReportError(dom->conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("missing disk device alias name for %s"), disk->dst); goto endjob; + } qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjEnterMonitor(vm); ret = qemuMonitorGetBlockStatsInfo(priv->mon, - qemu_dev_name, + disk->info.alias, &stats->rd_req, &stats->rd_bytes, &stats->wr_req, @@ -6770,7 +6711,6 @@ endjob: vm = NULL; cleanup: - VIR_FREE(qemu_dev_name); if (vm) virDomainObjUnlock(vm); return ret; -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:16PM +0000, Daniel P. Berrange wrote:
When starting a guest, give every device a unique alias. This will be used for the 'id' parameter in -device args in later patches. It can also be used to uniquely identify devices in the monitor
For old QEMU without -device, assign disk names based on QEMU's historical naming scheme.
* src/qemu/qemu_conf.c: Assign unique device aliases * src/qemu/qemu_driver.c: Remove obsolete qemudDiskDeviceName and use the device alias in eject & blockstats commands --- src/qemu/qemu_conf.c | 173 ++++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_driver.c | 104 ++++++----------------------- 2 files changed, 195 insertions(+), 82 deletions(-)
How would the user see the alias in practice ? They won't be dumped in the XML if I understand correctly so how to they get exposed ? ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Fri, Jan 15, 2010 at 05:42:31PM +0100, Daniel Veillard wrote:
On Fri, Jan 08, 2010 at 05:23:16PM +0000, Daniel P. Berrange wrote:
When starting a guest, give every device a unique alias. This will be used for the 'id' parameter in -device args in later patches. It can also be used to uniquely identify devices in the monitor
For old QEMU without -device, assign disk names based on QEMU's historical naming scheme.
* src/qemu/qemu_conf.c: Assign unique device aliases * src/qemu/qemu_driver.c: Remove obsolete qemudDiskDeviceName and use the device alias in eject & blockstats commands --- src/qemu/qemu_conf.c | 173 ++++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_driver.c | 104 ++++++----------------------- 2 files changed, 195 insertions(+), 82 deletions(-)
How would the user see the alias in practice ? They won't be dumped in the XML if I understand correctly so how to they get exposed ?
Yes, they'll appear in the XML dump. Here is a huge example: http://www.redhat.com/archives/libvir-list/2010-January/msg00186.html Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

The current character device syntax uses either -serial tty,path=/dev/ttyS2 Or -chardev tty,id=serial0,path=/dev/ttyS2 -serial chardev:serial0 With the new -device support, we now prefer -chardev file,id=serial0,path=/tmp/serial.log -device isa-serial,chardev=serial0 This patch changes the existing -chardev syntax to use this new scheme, and fallbacks to the old plain -serial syntax for old QEMU. The monitor device changes to -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor In addition, this patch adds --nodefaults, which kills off the default serial, parallel, vga and nic devices. THis avoids the need for us to explicitly turn each off --- src/qemu/qemu_conf.c | 97 +++++++++---------- src/qemu/qemu_driver.c | 7 ++ .../qemuxml2argv-channel-guestfwd.args | 2 +- .../qemuxml2argv-console-compat-chardev.args | 2 +- .../qemuxml2argv-parallel-tcp-chardev.args | 2 +- .../qemuxml2argv-serial-dev-chardev.args | 2 +- .../qemuxml2argv-serial-file-chardev.args | 2 +- .../qemuxml2argv-serial-many-chardev.args | 2 +- .../qemuxml2argv-serial-pty-chardev.args | 2 +- .../qemuxml2argv-serial-tcp-chardev.args | 2 +- .../qemuxml2argv-serial-tcp-telnet-chardev.args | 2 +- .../qemuxml2argv-serial-udp-chardev.args | 2 +- .../qemuxml2argv-serial-unix-chardev.args | 2 +- .../qemuxml2argv-serial-vc-chardev.args | 2 +- tests/qemuxml2argvtest.c | 29 +++--- 15 files changed, 81 insertions(+), 76 deletions(-) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 5dcd50f..eded887 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1592,6 +1592,9 @@ static char *qemuDiskDriveName(const virDomainDiskDefPtr disk) case VIR_DOMAIN_DISK_BUS_VIRTIO: ret = virAsprintf(&devname, "virtio%d", devid); break; + case VIR_DOMAIN_DISK_BUS_XEN: + ret = virAsprintf(&devname, "xenblk%d", devid); + break; default: qemudReportError(NULL, NULL, NULL, VIR_ERR_NO_SUPPORT, _("Unsupported disk name mapping for bus '%s'"), @@ -1991,43 +1994,42 @@ qemuBuildHostNetStr(virConnectPtr conn, /* This function outputs a -chardev command line option which describes only the * host side of the character device */ static void qemudBuildCommandLineChrDevChardevStr(virDomainChrDefPtr dev, - const char *const id, virBufferPtr buf) { bool telnet; switch(dev->type) { case VIR_DOMAIN_CHR_TYPE_NULL: - virBufferVSprintf(buf, "null,id=%s", id); + virBufferVSprintf(buf, "null,id=%s", dev->info.alias); break; case VIR_DOMAIN_CHR_TYPE_VC: - virBufferVSprintf(buf, "vc,id=%s", id); + virBufferVSprintf(buf, "vc,id=%s", dev->info.alias); break; case VIR_DOMAIN_CHR_TYPE_PTY: - virBufferVSprintf(buf, "pty,id=%s", id); + virBufferVSprintf(buf, "pty,id=%s", dev->info.alias); break; case VIR_DOMAIN_CHR_TYPE_DEV: - virBufferVSprintf(buf, "tty,id=%s,path=%s", id, dev->data.file.path); + virBufferVSprintf(buf, "tty,id=%s,path=%s", dev->info.alias, dev->data.file.path); break; case VIR_DOMAIN_CHR_TYPE_FILE: - virBufferVSprintf(buf, "file,id=%s,path=%s", id, dev->data.file.path); + virBufferVSprintf(buf, "file,id=%s,path=%s", dev->info.alias, dev->data.file.path); break; case VIR_DOMAIN_CHR_TYPE_PIPE: - virBufferVSprintf(buf, "pipe,id=%s,path=%s", id, dev->data.file.path); + virBufferVSprintf(buf, "pipe,id=%s,path=%s", dev->info.alias, dev->data.file.path); break; case VIR_DOMAIN_CHR_TYPE_STDIO: - virBufferVSprintf(buf, "stdio,id=%s", id); + virBufferVSprintf(buf, "stdio,id=%s", dev->info.alias); break; case VIR_DOMAIN_CHR_TYPE_UDP: virBufferVSprintf(buf, "udp,id=%s,host=%s,port=%s,localaddr=%s,localport=%s", - id, + dev->info.alias, dev->data.udp.connectHost, dev->data.udp.connectService, dev->data.udp.bindHost, @@ -2038,7 +2040,7 @@ static void qemudBuildCommandLineChrDevChardevStr(virDomainChrDefPtr dev, telnet = dev->data.tcp.protocol == VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET; virBufferVSprintf(buf, "socket,id=%s,host=%s,port=%s%s%s", - id, + dev->info.alias, dev->data.tcp.host, dev->data.tcp.service, telnet ? ",telnet" : "", @@ -2048,7 +2050,7 @@ static void qemudBuildCommandLineChrDevChardevStr(virDomainChrDefPtr dev, case VIR_DOMAIN_CHR_TYPE_UNIX: virBufferVSprintf(buf, "socket,id=%s,path=%s%s", - id, + dev->info.alias, dev->data.nix.path, dev->data.nix.listen ? ",server,nowait" : ""); break; @@ -2490,7 +2492,7 @@ int qemudBuildCommandLine(virConnectPtr conn, /* Use -chardev if it's available */ if (qemuCmdFlags & QEMUD_CMD_FLAG_CHARDEV) { - qemudBuildCommandLineChrDevChardevStr(monitor_chr, "monitor", &buf); + qemudBuildCommandLineChrDevChardevStr(monitor_chr, &buf); if (virBufferError(&buf)) { virBufferFreeAndReset(&buf); goto no_memory; @@ -2499,26 +2501,32 @@ int qemudBuildCommandLine(virConnectPtr conn, ADD_ARG_LIT("-chardev"); ADD_ARG(virBufferContentAndReset(&buf)); - if (monitor_json) - virBufferAddLit(&buf, "control,"); + virBufferVSprintf(&buf, "chardev=%s", monitor_chr->info.alias); - virBufferAddLit(&buf, "chardev:monitor"); - } + if (virBufferError(&buf)) { + virBufferFreeAndReset(&buf); + goto no_memory; + } - else { + ADD_ARG_LIT("-mon"); + if (monitor_json) + ADD_ARG_LIT("chardev=monitor,mode=control"); + else + ADD_ARG_LIT("chardev=monitor,mode=readline"); + } else { if (monitor_json) virBufferAddLit(&buf, "control,"); qemudBuildCommandLineChrDevStr(monitor_chr, &buf); - } - if (virBufferError(&buf)) { - virBufferFreeAndReset(&buf); - goto no_memory; - } + if (virBufferError(&buf)) { + virBufferFreeAndReset(&buf); + goto no_memory; + } - ADD_ARG_LIT("-monitor"); - ADD_ARG(virBufferContentAndReset(&buf)); + ADD_ARG_LIT("-monitor"); + ADD_ARG(virBufferContentAndReset(&buf)); + } } if (def->localtime) @@ -2781,14 +2789,10 @@ int qemudBuildCommandLine(virConnectPtr conn, virBuffer buf = VIR_BUFFER_INITIALIZER; virDomainChrDefPtr serial = def->serials[i]; - /* Use -chardev if it's available */ - if (qemuCmdFlags & QEMUD_CMD_FLAG_CHARDEV) { - char id[16]; - - if (snprintf(id, sizeof(id), "serial%i", i) > sizeof(id)) - goto error; - - qemudBuildCommandLineChrDevChardevStr(serial, id, &buf); + /* Use -chardev with -device if they are available */ + if ((qemuCmdFlags & QEMUD_CMD_FLAG_CHARDEV) && + (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) { + qemudBuildCommandLineChrDevChardevStr(serial, &buf); if (virBufferError(&buf)) { virBufferFreeAndReset(&buf); goto no_memory; @@ -2797,13 +2801,13 @@ int qemudBuildCommandLine(virConnectPtr conn, ADD_ARG_LIT("-chardev"); ADD_ARG(virBufferContentAndReset(&buf)); - virBufferVSprintf(&buf, "chardev:%s", id); + virBufferVSprintf(&buf, "isa-serial,chardev=%s", serial->info.alias); if (virBufferError(&buf)) { virBufferFreeAndReset(&buf); goto no_memory; } - ADD_ARG_LIT("-serial"); + ADD_ARG_LIT("-device"); ADD_ARG(virBufferContentAndReset(&buf)); } @@ -2831,14 +2835,10 @@ int qemudBuildCommandLine(virConnectPtr conn, virBuffer buf = VIR_BUFFER_INITIALIZER; virDomainChrDefPtr parallel = def->parallels[i]; - /* Use -chardev if it's available */ - if (qemuCmdFlags & QEMUD_CMD_FLAG_CHARDEV) { - char id[16]; - - if (snprintf(id, sizeof(id), "parallel%i", i) > sizeof(id)) - goto error; - - qemudBuildCommandLineChrDevChardevStr(parallel, id, &buf); + /* Use -chardev with -device if they are available */ + if ((qemuCmdFlags & QEMUD_CMD_FLAG_CHARDEV) && + (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) { + qemudBuildCommandLineChrDevChardevStr(parallel, &buf); if (virBufferError(&buf)) { virBufferFreeAndReset(&buf); goto no_memory; @@ -2847,13 +2847,13 @@ int qemudBuildCommandLine(virConnectPtr conn, ADD_ARG_LIT("-chardev"); ADD_ARG(virBufferContentAndReset(&buf)); - virBufferVSprintf(&buf, "chardev:%s", id); + virBufferVSprintf(&buf, "isa-parallel,chardev=%s", parallel->info.alias); if (virBufferError(&buf)) { virBufferFreeAndReset(&buf); goto no_memory; } - ADD_ARG_LIT("-parallel"); + ADD_ARG_LIT("-device"); ADD_ARG(virBufferContentAndReset(&buf)); } @@ -2872,13 +2872,8 @@ int qemudBuildCommandLine(virConnectPtr conn, for (i = 0 ; i < def->nchannels ; i++) { virBuffer buf = VIR_BUFFER_INITIALIZER; - char id[16]; - virDomainChrDefPtr channel = def->channels[i]; - if (snprintf(id, sizeof(id), "channel%i", i) > sizeof(id)) - goto error; - switch(channel->targetType) { case VIR_DOMAIN_CHR_TARGET_TYPE_GUESTFWD: if (!(qemuCmdFlags & QEMUD_CMD_FLAG_CHARDEV)) { @@ -2887,7 +2882,7 @@ int qemudBuildCommandLine(virConnectPtr conn, goto error; } - qemudBuildCommandLineChrDevChardevStr(channel, id, &buf); + qemudBuildCommandLineChrDevChardevStr(channel, &buf); if (virBufferError(&buf)) { virBufferFreeAndReset(&buf); goto no_memory; @@ -2900,7 +2895,7 @@ int qemudBuildCommandLine(virConnectPtr conn, int port = virSocketGetPort(channel->target.addr); virBufferVSprintf(&buf, "user,guestfwd=tcp:%s:%i-chardev:%s", - addr, port, id); + addr, port, channel->info.alias); VIR_FREE(addr); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 37b2730..6aabe3e 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -207,6 +207,11 @@ static int qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data) goto error; } + if (!(priv->monConfig->info.alias = strdup("monitor"))) { + virReportOOMError(NULL); + goto error; + } + if (!(monitorpath = virXPathString(NULL, "string(./monitor[1]/@path)", ctxt))) { qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, @@ -269,6 +274,8 @@ static int qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data) return 0; error: + virDomainChrDefFree(priv->monConfig); + priv->monConfig = NULL; VIR_FREE(nodes); return -1; } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args index deaff92..c3148df 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -chardev pipe,id=channel0,path=/tmp/guestfwd -net user,guestfwd=tcp:10.0.2.1:4600-chardev:channel0 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev pipe,id=channel0,path=/tmp/guestfwd -net user,guestfwd=tcp:10.0.2.1:4600-chardev:channel0 -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.args index fbb94f4..81ca364 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev pty,id=serial0 -serial chardev:serial0 -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev pty,id=serial0 -device isa-serial,chardev=serial0 -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.args index 45d1759..1961948 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -chardev socket,id=parallel0,host=127.0.0.1,port=9999,server,nowait -parallel chardev:parallel0 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev socket,id=parallel0,host=127.0.0.1,port=9999,server,nowait -device isa-parallel,chardev=parallel0 -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.args index 3036f13..d166f48 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev tty,id=serial0,path=/dev/ttyS2 -serial chardev:serial0 -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev tty,id=serial0,path=/dev/ttyS2 -device isa-serial,chardev=serial0 -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.args index 1dcec2b..b039bdf 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev file,id=serial0,path=/tmp/serial.log -serial chardev:serial0 -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev file,id=serial0,path=/tmp/serial.log -device isa-serial,chardev=serial0 -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.args index dd98fcb..419ea00 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev pty,id=serial0 -serial chardev:serial0 -chardev file,id=serial1,path=/tmp/serial.log -serial chardev:serial1 -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev pty,id=serial0 -device isa-serial,chardev=serial0 -chardev file,id=serial1,path=/tmp/serial.log -device isa-serial,chardev=serial1 -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.args index fbb94f4..81ca364 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev pty,id=serial0 -serial chardev:serial0 -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev pty,id=serial0 -device isa-serial,chardev=serial0 -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.args index 50cfeb0..526af51 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev socket,id=serial0,host=127.0.0.1,port=9999 -serial chardev:serial0 -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev socket,id=serial0,host=127.0.0.1,port=9999 -device isa-serial,chardev=serial0 -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.args index 86fa8af..842261b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev socket,id=serial0,host=127.0.0.1,port=9999,telnet,server,nowait -serial chardev:serial0 -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev socket,id=serial0,host=127.0.0.1,port=9999,telnet,server,nowait -device isa-serial,chardev=serial0 -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.args index 45421a4..7d7d2a8 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev udp,id=serial0,host=127.0.0.1,port=9998,localaddr=127.0.0.1,localport=9999 -serial chardev:serial0 -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev udp,id=serial0,host=127.0.0.1,port=9998,localaddr=127.0.0.1,localport=9999 -device isa-serial,chardev=serial0 -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.args index f291156..b326238 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev socket,id=serial0,path=/tmp/serial.sock -serial chardev:serial0 -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev socket,id=serial0,path=/tmp/serial.sock -device isa-serial,chardev=serial0 -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.args index a200225..4c7e654 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -monitor chardev:monitor -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -chardev vc,id=serial0 -serial chardev:serial0 -parallel none -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev vc,id=serial0 -device isa-serial,chardev=serial0 -usb diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 3b0aa2b..42d1579 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -48,9 +48,12 @@ static int testCompareXMLToArgvFiles(const char *xml, else vmdef->id = -1; + memset(&monitor_chr, 0, sizeof(monitor_chr)); monitor_chr.type = VIR_DOMAIN_CHR_TYPE_UNIX; monitor_chr.data.nix.path = (char *)"/tmp/test-monitor"; monitor_chr.data.nix.listen = 1; + if (!(monitor_chr.info.alias = strdup("monitor"))) + goto fail; flags = QEMUD_CMD_FLAG_VNC_COLON | QEMUD_CMD_FLAG_NO_REBOOT | @@ -273,19 +276,19 @@ mymain(int argc, char **argv) DO_TEST("parallel-tcp", 0); DO_TEST("console-compat", 0); - DO_TEST("serial-vc-chardev", QEMUD_CMD_FLAG_CHARDEV); - DO_TEST("serial-pty-chardev", QEMUD_CMD_FLAG_CHARDEV); - DO_TEST("serial-dev-chardev", QEMUD_CMD_FLAG_CHARDEV); - DO_TEST("serial-file-chardev", QEMUD_CMD_FLAG_CHARDEV); - DO_TEST("serial-unix-chardev", QEMUD_CMD_FLAG_CHARDEV); - DO_TEST("serial-tcp-chardev", QEMUD_CMD_FLAG_CHARDEV); - DO_TEST("serial-udp-chardev", QEMUD_CMD_FLAG_CHARDEV); - DO_TEST("serial-tcp-telnet-chardev", QEMUD_CMD_FLAG_CHARDEV); - DO_TEST("serial-many-chardev", QEMUD_CMD_FLAG_CHARDEV); - DO_TEST("parallel-tcp-chardev", QEMUD_CMD_FLAG_CHARDEV); - DO_TEST("console-compat-chardev", QEMUD_CMD_FLAG_CHARDEV); - - DO_TEST("channel-guestfwd", QEMUD_CMD_FLAG_CHARDEV); + DO_TEST("serial-vc-chardev", QEMUD_CMD_FLAG_CHARDEV|QEMUD_CMD_FLAG_DEVICE); + DO_TEST("serial-pty-chardev", QEMUD_CMD_FLAG_CHARDEV|QEMUD_CMD_FLAG_DEVICE); + DO_TEST("serial-dev-chardev", QEMUD_CMD_FLAG_CHARDEV|QEMUD_CMD_FLAG_DEVICE); + DO_TEST("serial-file-chardev", QEMUD_CMD_FLAG_CHARDEV|QEMUD_CMD_FLAG_DEVICE); + DO_TEST("serial-unix-chardev", QEMUD_CMD_FLAG_CHARDEV|QEMUD_CMD_FLAG_DEVICE); + DO_TEST("serial-tcp-chardev", QEMUD_CMD_FLAG_CHARDEV|QEMUD_CMD_FLAG_DEVICE); + DO_TEST("serial-udp-chardev", QEMUD_CMD_FLAG_CHARDEV|QEMUD_CMD_FLAG_DEVICE); + DO_TEST("serial-tcp-telnet-chardev", QEMUD_CMD_FLAG_CHARDEV|QEMUD_CMD_FLAG_DEVICE); + DO_TEST("serial-many-chardev", QEMUD_CMD_FLAG_CHARDEV|QEMUD_CMD_FLAG_DEVICE); + DO_TEST("parallel-tcp-chardev", QEMUD_CMD_FLAG_CHARDEV|QEMUD_CMD_FLAG_DEVICE); + DO_TEST("console-compat-chardev", QEMUD_CMD_FLAG_CHARDEV|QEMUD_CMD_FLAG_DEVICE); + + DO_TEST("channel-guestfwd", QEMUD_CMD_FLAG_CHARDEV|QEMUD_CMD_FLAG_DEVICE); DO_TEST("sound", 0); -- 1.6.5.2

On 01/08/2010 06:23 PM, Daniel P. Berrange wrote:
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 5dcd50f..eded887 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1592,6 +1592,9 @@ static char *qemuDiskDriveName(const virDomainDiskDefPtr disk) case VIR_DOMAIN_DISK_BUS_VIRTIO: ret = virAsprintf(&devname, "virtio%d", devid); break; + case VIR_DOMAIN_DISK_BUS_XEN: + ret = virAsprintf(&devname, "xenblk%d", devid); + break; default: qemudReportError(NULL, NULL, NULL, VIR_ERR_NO_SUPPORT, _("Unsupported disk name mapping for bus '%s'"),
Belongs in previous patch. Paolo

On Wed, Jan 13, 2010 at 03:56:03PM +0100, Paolo Bonzini wrote:
On 01/08/2010 06:23 PM, Daniel P. Berrange wrote:
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 5dcd50f..eded887 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1592,6 +1592,9 @@ static char *qemuDiskDriveName(const virDomainDiskDefPtr disk) case VIR_DOMAIN_DISK_BUS_VIRTIO: ret = virAsprintf(&devname, "virtio%d", devid); break; + case VIR_DOMAIN_DISK_BUS_XEN: + ret = virAsprintf(&devname, "xenblk%d", devid); + break; default: qemudReportError(NULL, NULL, NULL, VIR_ERR_NO_SUPPORT, _("Unsupported disk name mapping for bus '%s'"),
Belongs in previous patch.
Opps, not sure how that got in there ! Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Fri, Jan 08, 2010 at 05:23:17PM +0000, Daniel P. Berrange wrote:
The current character device syntax uses either
-serial tty,path=/dev/ttyS2
Or
-chardev tty,id=serial0,path=/dev/ttyS2 -serial chardev:serial0
With the new -device support, we now prefer
-chardev file,id=serial0,path=/tmp/serial.log -device isa-serial,chardev=serial0
This patch changes the existing -chardev syntax to use this new scheme, and fallbacks to the old plain -serial syntax for old QEMU.
The monitor device changes to
-chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor
In addition, this patch adds --nodefaults, which kills off the default serial, parallel, vga and nic devices. THis avoids the need for us to explicitly turn each off
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

The current syntax for watchdogs is -watchdog i6300esb The new syntax will now be -device i6300esb,id=watchdogNN,addr=<PCI-SLOT> --- src/qemu/qemu_conf.c | 91 ++++++++++++++++++-- .../qemuxml2argv-watchdog-device.args | 1 + .../qemuxml2argv-watchdog-device.xml | 23 +++++ tests/qemuxml2argvtest.c | 2 + 4 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.xml diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index eded887..fa16f8c 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1629,6 +1629,38 @@ qemuAssignDiskAliases(virDomainDefPtr def, int qemuCmdFlags) return 0; } +static int +qemuBuildDeviceAddressStr(virBufferPtr buf, + virDomainDeviceInfoPtr info) +{ + if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + if (info->addr.pci.domain != 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s", + _("Only PCI device addresses with domain=0 are supported")); + return -1; + } + if (info->addr.pci.bus != 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s", + _("Only PCI device addresses with bus=0 are supported")); + return -1; + } + if (info->addr.pci.function != 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s", + _("Only PCI device addresses with function=0 are supported")); + return -1; + } + + /* XXX + * When QEMU grows support for > 1 PCI bus, then pci.0 changes + * to pci.1, pci.2, etc + * When QEMU grows support for > 1 PCI domain, then pci.0 change + * to pciNN.0 where NN is the domain number + */ + virBufferVSprintf(buf, ",bus=pci.0,addr=0x%x", info->addr.pci.slot); + } + return 0; +} + static const char * qemuNetTypeToHostNet(int type) @@ -1991,7 +2023,36 @@ qemuBuildHostNetStr(virConnectPtr conn, return 0; } -/* This function outputs a -chardev command line option which describes only the + +static char *qemuBuildWatchdogDevStr(virDomainWatchdogDefPtr dev) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + + const char *model = virDomainWatchdogModelTypeToString(dev->model); + if (!model) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("missing watchdog model")); + goto error; + } + + virBufferVSprintf(&buf, "%s", model); + virBufferVSprintf(&buf, ",id=%s", dev->info.alias); + if (qemuBuildDeviceAddressStr(&buf, &dev->info) < 0) + goto error; + + if (virBufferError(&buf)) { + virReportOOMError(NULL); + goto error; + } + + return virBufferContentAndReset(&buf); + +error: + virBufferFreeAndReset(&buf); + return NULL; +} + +/* this function outputs a -chardev command line option which describes only the * host side of the character device */ static void qemudBuildCommandLineChrDevChardevStr(virDomainChrDefPtr dev, virBufferPtr buf) @@ -3086,14 +3147,28 @@ int qemudBuildCommandLine(virConnectPtr conn, /* Add watchdog hardware */ if (def->watchdog) { virDomainWatchdogDefPtr watchdog = def->watchdog; - const char *model = virDomainWatchdogModelTypeToString(watchdog->model); - if (!model) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("invalid watchdog model")); - goto error; + char *optstr; + + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { + ADD_ARG_LIT("-device"); + + optstr = qemuBuildWatchdogDevStr(watchdog); + if (!optstr) + goto error; + } else { + ADD_ARG_LIT("-watchdog"); + + const char *model = virDomainWatchdogModelTypeToString(watchdog->model); + if (!model) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("missing watchdog model")); + goto error; + } + + if (!(optstr = strdup(model))) + goto no_memory; } - ADD_ARG_LIT("-watchdog"); - ADD_ARG_LIT(model); + ADD_ARG(optstr); const char *action = virDomainWatchdogActionTypeToString(watchdog->action); if (!action) { diff --git a/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.args b/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.args new file mode 100644 index 0000000..5f3a428 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -device ib700,id=watchdog0 -watchdog-action poweroff diff --git a/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.xml new file mode 100644 index 0000000..9b2ffdf --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.xml @@ -0,0 +1,23 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219200</memory> + <currentMemory>219200</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + </disk> + <watchdog model='ib700' action='poweroff'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 42d1579..6bfc217 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -290,6 +290,8 @@ mymain(int argc, char **argv) DO_TEST("channel-guestfwd", QEMUD_CMD_FLAG_CHARDEV|QEMUD_CMD_FLAG_DEVICE); + DO_TEST("watchdog", 0); + DO_TEST("watchdog-device", QEMUD_CMD_FLAG_DEVICE); DO_TEST("sound", 0); DO_TEST("hostdev-usb-product", 0); -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:18PM +0000, Daniel P. Berrange wrote:
The current syntax for watchdogs is
-watchdog i6300esb
The new syntax will now be
-device i6300esb,id=watchdogNN,addr=<PCI-SLOT> --- src/qemu/qemu_conf.c | 91 ++++++++++++++++++-- .../qemuxml2argv-watchdog-device.args | 1 + .../qemuxml2argv-watchdog-device.xml | 23 +++++ tests/qemuxml2argvtest.c | 2 + 4 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.xml
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index eded887..fa16f8c 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1629,6 +1629,38 @@ qemuAssignDiskAliases(virDomainDefPtr def, int qemuCmdFlags) return 0; }
+static int +qemuBuildDeviceAddressStr(virBufferPtr buf, + virDomainDeviceInfoPtr info) +{ + if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + if (info->addr.pci.domain != 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s", + _("Only PCI device addresses with domain=0 are supported")); + return -1; + } + if (info->addr.pci.bus != 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s", + _("Only PCI device addresses with bus=0 are supported")); + return -1; + } + if (info->addr.pci.function != 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s", + _("Only PCI device addresses with function=0 are supported")); + return -1; + } + + /* XXX + * When QEMU grows support for > 1 PCI bus, then pci.0 changes + * to pci.1, pci.2, etc + * When QEMU grows support for > 1 PCI domain, then pci.0 change + * to pciNN.0 where NN is the domain number + */ + virBufferVSprintf(buf, ",bus=pci.0,addr=0x%x", info->addr.pci.slot); + } + return 0; +} +
static const char * qemuNetTypeToHostNet(int type) @@ -1991,7 +2023,36 @@ qemuBuildHostNetStr(virConnectPtr conn, return 0; }
-/* This function outputs a -chardev command line option which describes only the + +static char *qemuBuildWatchdogDevStr(virDomainWatchdogDefPtr dev) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + + const char *model = virDomainWatchdogModelTypeToString(dev->model); + if (!model) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("missing watchdog model")); + goto error; + } + + virBufferVSprintf(&buf, "%s", model); + virBufferVSprintf(&buf, ",id=%s", dev->info.alias); + if (qemuBuildDeviceAddressStr(&buf, &dev->info) < 0) + goto error; + + if (virBufferError(&buf)) { + virReportOOMError(NULL); + goto error; + } + + return virBufferContentAndReset(&buf); + +error: + virBufferFreeAndReset(&buf); + return NULL; +} + +/* this function outputs a -chardev command line option which describes only the * host side of the character device */ static void qemudBuildCommandLineChrDevChardevStr(virDomainChrDefPtr dev, virBufferPtr buf) @@ -3086,14 +3147,28 @@ int qemudBuildCommandLine(virConnectPtr conn, /* Add watchdog hardware */ if (def->watchdog) { virDomainWatchdogDefPtr watchdog = def->watchdog; - const char *model = virDomainWatchdogModelTypeToString(watchdog->model); - if (!model) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("invalid watchdog model")); - goto error; + char *optstr; + + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { + ADD_ARG_LIT("-device"); + + optstr = qemuBuildWatchdogDevStr(watchdog); + if (!optstr) + goto error; + } else { + ADD_ARG_LIT("-watchdog"); + + const char *model = virDomainWatchdogModelTypeToString(watchdog->model); + if (!model) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("missing watchdog model")); + goto error; + } + + if (!(optstr = strdup(model))) + goto no_memory; } - ADD_ARG_LIT("-watchdog"); - ADD_ARG_LIT(model); + ADD_ARG(optstr);
const char *action = virDomainWatchdogActionTypeToString(watchdog->action); if (!action) { diff --git a/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.args b/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.args new file mode 100644 index 0000000..5f3a428 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -device ib700,id=watchdog0 -watchdog-action poweroff diff --git a/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.xml new file mode 100644 index 0000000..9b2ffdf --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.xml @@ -0,0 +1,23 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219200</memory> + <currentMemory>219200</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + </disk> + <watchdog model='ib700' action='poweroff'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 42d1579..6bfc217 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -290,6 +290,8 @@ mymain(int argc, char **argv)
DO_TEST("channel-guestfwd", QEMUD_CMD_FLAG_CHARDEV|QEMUD_CMD_FLAG_DEVICE);
+ DO_TEST("watchdog", 0); + DO_TEST("watchdog-device", QEMUD_CMD_FLAG_DEVICE); DO_TEST("sound", 0);
DO_TEST("hostdev-usb-product", 0);
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

The current syntax for audio devices is a horrible multiplexed arg -soundhw sb16,pcspk,ac97 The new syntax is -device sb16,id=sound0 or -device AC97,id=sound1,addr=<PCI SLOT> NB, pcspk still uses the old -soundhw syntax --- src/qemu/qemu_conf.c | 97 ++++++++++++++++---- .../qemuxml2argv-sound-device.args | 1 + .../qemuxml2argvdata/qemuxml2argv-sound-device.xml | 26 +++++ tests/qemuxml2argvtest.c | 1 + 4 files changed, 106 insertions(+), 19 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-sound-device.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-sound-device.xml diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index fa16f8c..067fe42 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -2052,7 +2052,44 @@ error: return NULL; } -/* this function outputs a -chardev command line option which describes only the + +static char * +qemuBuildSoundDevStr(virDomainSoundDefPtr sound) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + const char *model = virDomainSoundModelTypeToString(sound->model); + + if (!model) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("invalid sound model")); + goto error; + } + + /* Hack for 2 wierdly unusal devices name in QEMU */ + if (STREQ(model, "es1370")) + model = "ES1370"; + else if (STREQ(model, "ac97")) + model = "AC97"; + + virBufferVSprintf(&buf, "%s", model); + virBufferVSprintf(&buf, ",id=%s", sound->info.alias); + if (qemuBuildDeviceAddressStr(&buf, &sound->info) < 0) + goto error; + + if (virBufferError(&buf)) { + virReportOOMError(NULL); + goto error; + } + + return virBufferContentAndReset(&buf); + +error: + virBufferFreeAndReset(&buf); + return NULL; +} + + +/* This function outputs a -chardev command line option which describes only the * host side of the character device */ static void qemudBuildCommandLineChrDevChardevStr(virDomainChrDefPtr dev, virBufferPtr buf) @@ -3121,27 +3158,49 @@ int qemudBuildCommandLine(virConnectPtr conn, /* Add sound hardware */ if (def->nsounds) { - int size = 100; - char *modstr; - if (VIR_ALLOC_N(modstr, size+1) < 0) - goto no_memory; + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { + for (i = 0 ; i < def->nsounds ; i++) { + virDomainSoundDefPtr sound = def->sounds[i]; + char *str = NULL; + + /* Sadly pcspk device doesn't use -device syntax. Fortunately + * we don't need to set any PCI address on it, so we don't + * mind too much */ + if (sound->model == VIR_DOMAIN_SOUND_MODEL_PCSPK) { + ADD_ARG_LIT("-soundhw"); + ADD_ARG_LIT("pcspk"); + } else { + ADD_ARG_LIT("-device"); - for (i = 0 ; i < def->nsounds && size > 0 ; i++) { - virDomainSoundDefPtr sound = def->sounds[i]; - const char *model = virDomainSoundModelTypeToString(sound->model); - if (!model) { - VIR_FREE(modstr); - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("invalid sound model")); - goto error; + if (!(str = qemuBuildSoundDevStr(sound))) + goto error; + + ADD_ARG(str); + } + } + } else { + int size = 100; + char *modstr; + if (VIR_ALLOC_N(modstr, size+1) < 0) + goto no_memory; + + for (i = 0 ; i < def->nsounds && size > 0 ; i++) { + virDomainSoundDefPtr sound = def->sounds[i]; + const char *model = virDomainSoundModelTypeToString(sound->model); + if (!model) { + VIR_FREE(modstr); + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("invalid sound model")); + goto error; + } + strncat(modstr, model, size); + size -= strlen(model); + if (i < (def->nsounds - 1)) + strncat(modstr, ",", size--); } - strncat(modstr, model, size); - size -= strlen(model); - if (i < (def->nsounds - 1)) - strncat(modstr, ",", size--); + ADD_ARG_LIT("-soundhw"); + ADD_ARG(modstr); } - ADD_ARG_LIT("-soundhw"); - ADD_ARG(modstr); } /* Add watchdog hardware */ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args b/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args new file mode 100644 index 0000000..31ac0ee --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -soundhw pcspk -device ES1370,id=sound1 -device sb16,id=sound2 -device AC97,id=sound3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-sound-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-sound-device.xml new file mode 100644 index 0000000..8c33e6c --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-sound-device.xml @@ -0,0 +1,26 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219200</memory> + <currentMemory>219200</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + </disk> + <sound model='pcspk'/> + <sound model='es1370'/> + <sound model='sb16'/> + <sound model='ac97'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 6bfc217..55e7d58 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -293,6 +293,7 @@ mymain(int argc, char **argv) DO_TEST("watchdog", 0); DO_TEST("watchdog-device", QEMUD_CMD_FLAG_DEVICE); DO_TEST("sound", 0); + DO_TEST("sound-device", QEMUD_CMD_FLAG_DEVICE); DO_TEST("hostdev-usb-product", 0); DO_TEST("hostdev-usb-address", 0); -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:19PM +0000, Daniel P. Berrange wrote:
The current syntax for audio devices is a horrible multiplexed arg
-soundhw sb16,pcspk,ac97
The new syntax is
-device sb16,id=sound0
or
-device AC97,id=sound1,addr=<PCI SLOT>
NB, pcspk still uses the old -soundhw syntax --- src/qemu/qemu_conf.c | 97 ++++++++++++++++---- .../qemuxml2argv-sound-device.args | 1 + .../qemuxml2argvdata/qemuxml2argv-sound-device.xml | 26 +++++ tests/qemuxml2argvtest.c | 1 + 4 files changed, 106 insertions(+), 19 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-sound-device.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-sound-device.xml
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index fa16f8c..067fe42 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -2052,7 +2052,44 @@ error: return NULL; }
-/* this function outputs a -chardev command line option which describes only the + +static char * +qemuBuildSoundDevStr(virDomainSoundDefPtr sound) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + const char *model = virDomainSoundModelTypeToString(sound->model); + + if (!model) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("invalid sound model")); + goto error; + } + + /* Hack for 2 wierdly unusal devices name in QEMU */ + if (STREQ(model, "es1370")) + model = "ES1370"; + else if (STREQ(model, "ac97")) + model = "AC97"; + + virBufferVSprintf(&buf, "%s", model); + virBufferVSprintf(&buf, ",id=%s", sound->info.alias); + if (qemuBuildDeviceAddressStr(&buf, &sound->info) < 0) + goto error; + + if (virBufferError(&buf)) { + virReportOOMError(NULL); + goto error; + } + + return virBufferContentAndReset(&buf); + +error: + virBufferFreeAndReset(&buf); + return NULL; +} + + +/* This function outputs a -chardev command line option which describes only the * host side of the character device */ static void qemudBuildCommandLineChrDevChardevStr(virDomainChrDefPtr dev, virBufferPtr buf) @@ -3121,27 +3158,49 @@ int qemudBuildCommandLine(virConnectPtr conn,
/* Add sound hardware */ if (def->nsounds) { - int size = 100; - char *modstr; - if (VIR_ALLOC_N(modstr, size+1) < 0) - goto no_memory; + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { + for (i = 0 ; i < def->nsounds ; i++) { + virDomainSoundDefPtr sound = def->sounds[i]; + char *str = NULL; + + /* Sadly pcspk device doesn't use -device syntax. Fortunately + * we don't need to set any PCI address on it, so we don't + * mind too much */ + if (sound->model == VIR_DOMAIN_SOUND_MODEL_PCSPK) { + ADD_ARG_LIT("-soundhw"); + ADD_ARG_LIT("pcspk"); + } else { + ADD_ARG_LIT("-device");
- for (i = 0 ; i < def->nsounds && size > 0 ; i++) { - virDomainSoundDefPtr sound = def->sounds[i]; - const char *model = virDomainSoundModelTypeToString(sound->model); - if (!model) { - VIR_FREE(modstr); - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("invalid sound model")); - goto error; + if (!(str = qemuBuildSoundDevStr(sound))) + goto error; + + ADD_ARG(str); + } + } + } else { + int size = 100; + char *modstr; + if (VIR_ALLOC_N(modstr, size+1) < 0) + goto no_memory; + + for (i = 0 ; i < def->nsounds && size > 0 ; i++) { + virDomainSoundDefPtr sound = def->sounds[i]; + const char *model = virDomainSoundModelTypeToString(sound->model); + if (!model) { + VIR_FREE(modstr); + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("invalid sound model")); + goto error; + } + strncat(modstr, model, size); + size -= strlen(model); + if (i < (def->nsounds - 1)) + strncat(modstr, ",", size--); } - strncat(modstr, model, size); - size -= strlen(model); - if (i < (def->nsounds - 1)) - strncat(modstr, ",", size--); + ADD_ARG_LIT("-soundhw"); + ADD_ARG(modstr); } - ADD_ARG_LIT("-soundhw"); - ADD_ARG(modstr); }
/* Add watchdog hardware */ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args b/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args new file mode 100644 index 0000000..31ac0ee --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -soundhw pcspk -device ES1370,id=sound1 -device sb16,id=sound2 -device AC97,id=sound3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-sound-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-sound-device.xml new file mode 100644 index 0000000..8c33e6c --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-sound-device.xml @@ -0,0 +1,26 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219200</memory> + <currentMemory>219200</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + </disk> + <sound model='pcspk'/> + <sound model='es1370'/> + <sound model='sb16'/> + <sound model='ac97'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 6bfc217..55e7d58 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -293,6 +293,7 @@ mymain(int argc, char **argv) DO_TEST("watchdog", 0); DO_TEST("watchdog-device", QEMUD_CMD_FLAG_DEVICE); DO_TEST("sound", 0); + DO_TEST("sound-device", QEMUD_CMD_FLAG_DEVICE);
DO_TEST("hostdev-usb-product", 0); DO_TEST("hostdev-usb-address", 0);
ACK Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

The current preferred syntax for disk drives uses -drive file=/vms/plain.qcow,if=virtio,index=0,boot=on,format=qcow The new syntax splits this up into a pair of linked args -drive file=/vms/plain.qcow,if=none,id=drive-virtio-0,format=qcow2 -device virtio-blk-pci,drive=drive-virtio-0,id=virtio-0,addr=<PCI SLOT> SCSI/IDE devices also get a bus property linking them to the controller -device scsi-disk,drive=drive-scsi0-0-0,id=scsi0-0-0,bus=scsi0.0,scsi-id=0 -device ide-drive,drive=drive-ide0-0-0,id=ide0-0-0,bus=ide0,unit=0 --- src/qemu/qemu_conf.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 148 insertions(+), 9 deletions(-) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 067fe42..8b8455d 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1852,17 +1852,26 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk, virBufferVSprintf(&opt, "file=%s,", disk->src); } } - virBufferVSprintf(&opt, "if=%s", bus); + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) + virBufferAddLit(&opt, "if=none"); + else + virBufferVSprintf(&opt, "if=%s", bus); + if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) virBufferAddLit(&opt, ",media=cdrom"); - if (busid == -1 && unitid == -1) { - if (idx != -1) - virBufferVSprintf(&opt, ",index=%d", idx); + + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { + virBufferVSprintf(&opt, ",id=drive-%s", disk->info.alias); } else { - if (busid != -1) - virBufferVSprintf(&opt, ",bus=%d", busid); - if (unitid != -1) - virBufferVSprintf(&opt, ",unit=%d", unitid); + if (busid == -1 && unitid == -1) { + if (idx != -1) + virBufferVSprintf(&opt, ",index=%d", idx); + } else { + if (busid != -1) + virBufferVSprintf(&opt, ",bus=%d", busid); + if (unitid != -1) + virBufferVSprintf(&opt, ",unit=%d", unitid); + } } if (bootable && disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) @@ -1901,6 +1910,91 @@ error: return NULL; } +static int +qemuBuildDriveDevStr(virConnectPtr conn, + virDomainDiskDefPtr disk, + char **str) +{ + virBuffer opt = VIR_BUFFER_INITIALIZER; + const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus); + int idx = virDiskNameToIndex(disk->dst); + + if (idx < 0) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("unsupported disk type '%s'"), disk->dst); + goto error; + } + + switch (disk->bus) { + case VIR_DOMAIN_DISK_BUS_IDE: + virBufferAddLit(&opt, "ide-drive"); + virBufferVSprintf(&opt, ",bus=ide.%d,unit=%d", + disk->info.addr.drive.bus, + disk->info.addr.drive.unit); + break; + case VIR_DOMAIN_DISK_BUS_SCSI: + virBufferAddLit(&opt, "scsi-disk"); + virBufferVSprintf(&opt, ",bus=scsi%d.%d,scsi-id=%d", + disk->info.addr.drive.controller, + disk->info.addr.drive.bus, + disk->info.addr.drive.unit); + break; + case VIR_DOMAIN_DISK_BUS_VIRTIO: + virBufferAddLit(&opt, "virtio-blk-pci"); + qemuBuildDeviceAddressStr(&opt, &disk->info); + break; + + default: + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("unsupported disk bus '%s' with device setup"), bus); + goto error; + } + virBufferVSprintf(&opt, ",drive=drive-%s", disk->info.alias); + virBufferVSprintf(&opt, ",id=%s", disk->info.alias); + + *str = virBufferContentAndReset(&opt); + return 0; + +error: + virBufferFreeAndReset(&opt); + *str = NULL; + return -1; +} + + +static char * +qemuBuildControllerDevStr(virDomainControllerDefPtr def) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + + switch (def->type) { + case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: + virBufferAddLit(&buf, "lsi"); + virBufferVSprintf(&buf, ",id=scsi%d", def->idx); + break; + + case VIR_DOMAIN_CONTROLLER_TYPE_IDE: + virBufferAddLit(&buf, "piix4-ide"); + virBufferVSprintf(&buf, ",id=ide%d", def->idx); + break; + + default: + goto error; + } + + if (qemuBuildDeviceAddressStr(&buf, &def->info) < 0) + goto error; + + if (virBufferError(&buf)) + goto error; + + return virBufferContentAndReset(&buf); + +error: + virBufferFreeAndReset(&buf); + return NULL; +} + int qemuBuildNicStr(virConnectPtr conn, @@ -2692,6 +2786,21 @@ int qemudBuildCommandLine(virConnectPtr conn, } } + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { + for (i = 0 ; i < def->ncontrollers ; i++) { + char *scsi; + if (def->controllers[i]->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) + continue; + + ADD_ARG_LIT("-device"); + + if (!(scsi = qemuBuildControllerDevStr(def->controllers[i]))) + goto no_memory; + + ADD_ARG(scsi); + } + } + /* If QEMU supports -drive param instead of old -hda, -hdb, -cdrom .. */ if (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE) { int bootCD = 0, bootFloppy = 0, bootDisk = 0; @@ -2717,6 +2826,7 @@ int qemudBuildCommandLine(virConnectPtr conn, char *optstr; int bootable = 0; virDomainDiskDefPtr disk = def->disks[i]; + int withDeviceArg = 0; if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) { if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) { @@ -2746,9 +2856,38 @@ int qemudBuildCommandLine(virConnectPtr conn, ADD_ARG_LIT("-drive"); - if (!(optstr = qemuBuildDriveStr(disk, bootable, qemuCmdFlags))) + /* Unfortunately it is nt possible to use + -device for floppys, or Xen paravirt + devices. Fortunately, those don't need + static PCI addresses, so we don't really + care that we can't use -device */ + if ((qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) && + (disk->bus != VIR_DOMAIN_DISK_BUS_XEN)) + withDeviceArg = 1; + if (!(optstr = qemuBuildDriveStr(disk, bootable, + (withDeviceArg ? qemuCmdFlags : + (qemuCmdFlags & ~QEMUD_CMD_FLAG_DEVICE))))) goto error; ADD_ARG(optstr); + + if (withDeviceArg) { + if (disk->bus == VIR_DOMAIN_DISK_BUS_FDC) { + char *fdc; + ADD_ARG_LIT("-global"); + + if (virAsprintf(&fdc, "isa-fdc,drive%c=drive-%s", + disk->info.addr.drive.unit ? 'B' : 'A', + disk->info.alias) < 0) + goto no_memory; + ADD_ARG(fdc); + } else { + ADD_ARG_LIT("-device"); + + if (qemuBuildDriveDevStr(conn, disk, &optstr) < 0) + goto error; + ADD_ARG(optstr); + } + } } } else { for (i = 0 ; i < def->ndisks ; i++) { -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:20PM +0000, Daniel P. Berrange wrote:
The current preferred syntax for disk drives uses
-drive file=/vms/plain.qcow,if=virtio,index=0,boot=on,format=qcow
The new syntax splits this up into a pair of linked args
-drive file=/vms/plain.qcow,if=none,id=drive-virtio-0,format=qcow2 -device virtio-blk-pci,drive=drive-virtio-0,id=virtio-0,addr=<PCI SLOT>
SCSI/IDE devices also get a bus property linking them to the controller
-device scsi-disk,drive=drive-scsi0-0-0,id=scsi0-0-0,bus=scsi0.0,scsi-id=0 -device ide-drive,drive=drive-ide0-0-0,id=ide0-0-0,bus=ide0,unit=0 --- src/qemu/qemu_conf.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 148 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 067fe42..8b8455d 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1852,17 +1852,26 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk, virBufferVSprintf(&opt, "file=%s,", disk->src); } } - virBufferVSprintf(&opt, "if=%s", bus); + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) + virBufferAddLit(&opt, "if=none"); + else + virBufferVSprintf(&opt, "if=%s", bus); + if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) virBufferAddLit(&opt, ",media=cdrom"); - if (busid == -1 && unitid == -1) { - if (idx != -1) - virBufferVSprintf(&opt, ",index=%d", idx); + + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { + virBufferVSprintf(&opt, ",id=drive-%s", disk->info.alias); } else { - if (busid != -1) - virBufferVSprintf(&opt, ",bus=%d", busid); - if (unitid != -1) - virBufferVSprintf(&opt, ",unit=%d", unitid); + if (busid == -1 && unitid == -1) { + if (idx != -1) + virBufferVSprintf(&opt, ",index=%d", idx); + } else { + if (busid != -1) + virBufferVSprintf(&opt, ",bus=%d", busid); + if (unitid != -1) + virBufferVSprintf(&opt, ",unit=%d", unitid); + } } if (bootable && disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) @@ -1901,6 +1910,91 @@ error: return NULL; }
+static int +qemuBuildDriveDevStr(virConnectPtr conn, + virDomainDiskDefPtr disk, + char **str) +{ + virBuffer opt = VIR_BUFFER_INITIALIZER; + const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus); + int idx = virDiskNameToIndex(disk->dst); + + if (idx < 0) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("unsupported disk type '%s'"), disk->dst); + goto error; + } + + switch (disk->bus) { + case VIR_DOMAIN_DISK_BUS_IDE: + virBufferAddLit(&opt, "ide-drive"); + virBufferVSprintf(&opt, ",bus=ide.%d,unit=%d", + disk->info.addr.drive.bus, + disk->info.addr.drive.unit); + break; + case VIR_DOMAIN_DISK_BUS_SCSI: + virBufferAddLit(&opt, "scsi-disk"); + virBufferVSprintf(&opt, ",bus=scsi%d.%d,scsi-id=%d", + disk->info.addr.drive.controller, + disk->info.addr.drive.bus, + disk->info.addr.drive.unit); + break; + case VIR_DOMAIN_DISK_BUS_VIRTIO: + virBufferAddLit(&opt, "virtio-blk-pci"); + qemuBuildDeviceAddressStr(&opt, &disk->info); + break; + + default: + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("unsupported disk bus '%s' with device setup"), bus); + goto error; + } + virBufferVSprintf(&opt, ",drive=drive-%s", disk->info.alias); + virBufferVSprintf(&opt, ",id=%s", disk->info.alias); + + *str = virBufferContentAndReset(&opt); + return 0; + +error: + virBufferFreeAndReset(&opt); + *str = NULL; + return -1; +} + + +static char * +qemuBuildControllerDevStr(virDomainControllerDefPtr def) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + + switch (def->type) { + case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: + virBufferAddLit(&buf, "lsi"); + virBufferVSprintf(&buf, ",id=scsi%d", def->idx); + break; + + case VIR_DOMAIN_CONTROLLER_TYPE_IDE: + virBufferAddLit(&buf, "piix4-ide"); + virBufferVSprintf(&buf, ",id=ide%d", def->idx); + break; + + default: + goto error; + } + + if (qemuBuildDeviceAddressStr(&buf, &def->info) < 0) + goto error; + + if (virBufferError(&buf)) + goto error; + + return virBufferContentAndReset(&buf); + +error: + virBufferFreeAndReset(&buf); + return NULL; +} +
int qemuBuildNicStr(virConnectPtr conn, @@ -2692,6 +2786,21 @@ int qemudBuildCommandLine(virConnectPtr conn, } }
+ if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { + for (i = 0 ; i < def->ncontrollers ; i++) { + char *scsi; + if (def->controllers[i]->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) + continue; + + ADD_ARG_LIT("-device"); + + if (!(scsi = qemuBuildControllerDevStr(def->controllers[i]))) + goto no_memory; + + ADD_ARG(scsi); + } + } + /* If QEMU supports -drive param instead of old -hda, -hdb, -cdrom .. */ if (qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE) { int bootCD = 0, bootFloppy = 0, bootDisk = 0; @@ -2717,6 +2826,7 @@ int qemudBuildCommandLine(virConnectPtr conn, char *optstr; int bootable = 0; virDomainDiskDefPtr disk = def->disks[i]; + int withDeviceArg = 0;
if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) { if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) { @@ -2746,9 +2856,38 @@ int qemudBuildCommandLine(virConnectPtr conn,
ADD_ARG_LIT("-drive");
- if (!(optstr = qemuBuildDriveStr(disk, bootable, qemuCmdFlags))) + /* Unfortunately it is nt possible to use + -device for floppys, or Xen paravirt + devices. Fortunately, those don't need + static PCI addresses, so we don't really + care that we can't use -device */ + if ((qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) && + (disk->bus != VIR_DOMAIN_DISK_BUS_XEN)) + withDeviceArg = 1; + if (!(optstr = qemuBuildDriveStr(disk, bootable, + (withDeviceArg ? qemuCmdFlags : + (qemuCmdFlags & ~QEMUD_CMD_FLAG_DEVICE))))) goto error; ADD_ARG(optstr); + + if (withDeviceArg) { + if (disk->bus == VIR_DOMAIN_DISK_BUS_FDC) { + char *fdc; + ADD_ARG_LIT("-global"); + + if (virAsprintf(&fdc, "isa-fdc,drive%c=drive-%s", + disk->info.addr.drive.unit ? 'B' : 'A', + disk->info.alias) < 0) + goto no_memory; + ADD_ARG(fdc); + } else { + ADD_ARG_LIT("-device"); + + if (qemuBuildDriveDevStr(conn, disk, &optstr) < 0) + goto error; + ADD_ARG(optstr); + } + } } } else { for (i = 0 ; i < def->ndisks ; i++) {
The more I read those command line, the more I wonder when they will invent their own structured definition format ... ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

The current syntax uses a pair of args -net nic,macaddr=52:54:00:56:6c:55,vlan=3,model=pcnet,name=pcnet.0 -net user,vlan=3,name=user.0 The new syntax does not need the vlan craziness anymore, and so has a simplified pair of args -netdev user,id=user.0 -device pcnet,netdev=user.0,id=pcnet.0,mac=52:54:00:56:6c:55,addr=<PCI SLOT> --- src/qemu/qemu_conf.c | 175 ++++++++++++++++---- .../qemuxml2argv-net-virtio-device.args | 1 + .../qemuxml2argv-net-virtio-device.xml | 26 +++ tests/qemuxml2argvtest.c | 1 + 4 files changed, 174 insertions(+), 29 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.xml diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 8b8455d..709c3f4 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1488,6 +1488,8 @@ qemuAssignDeviceAliases(virDomainDefPtr def) if (virAsprintf(&def->nets[i]->info.alias, "nic%d", i) < 0) goto no_memory; } + if (virAsprintf(&def->nets[i]->hostnet_name, "netdev%d", i) < 0) + goto no_memory; } for (i = 0; i < def->nsounds ; i++) { @@ -2021,6 +2023,41 @@ qemuBuildNicStr(virConnectPtr conn, return 0; } +static char * +qemuBuildNicDevStr(virDomainNetDefPtr net) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + const char *nic; + + if (!net->model) { + nic = "rtl8139"; + } else if (STREQ(net->model, "virtio")) { + nic = "virtio-net-pci"; + } else { + nic = net->model; + } + + virBufferVSprintf(&buf, "%s,netdev=%s", nic, net->hostnet_name); + virBufferVSprintf(&buf, ",id=%s", net->info.alias); + virBufferVSprintf(&buf, ",mac=%02x:%02x:%02x:%02x:%02x:%02x", + net->mac[0], net->mac[1], + net->mac[2], net->mac[3], + net->mac[4], net->mac[5]); + if (qemuBuildDeviceAddressStr(&buf, &net->info) < 0) + goto error; + + if (virBufferError(&buf)) { + virReportOOMError(NULL); + goto error; + } + + return virBufferContentAndReset(&buf); + +error: + virBufferFreeAndReset(&buf); + return NULL; +} + int qemuBuildHostNetStr(virConnectPtr conn, virDomainNetDefPtr net, @@ -2118,6 +2155,88 @@ qemuBuildHostNetStr(virConnectPtr conn, } +static int +qemuBuildNetDevStr(virConnectPtr conn, + virDomainNetDefPtr net, + const char *tapfd, + char **str) +{ + switch (net->type) { + case VIR_DOMAIN_NET_TYPE_NETWORK: + case VIR_DOMAIN_NET_TYPE_BRIDGE: + if (virAsprintf(str, "tap,fd=%s,id=%s", + tapfd, net->hostnet_name) < 0) { + virReportOOMError(conn); + return -1; + } + break; + + case VIR_DOMAIN_NET_TYPE_ETHERNET: + { + virBuffer buf = VIR_BUFFER_INITIALIZER; + + virBufferAddLit(&buf, "tap"); + if (net->ifname) + virBufferVSprintf(&buf, ",ifname=%s", net->ifname); + if (net->data.ethernet.script) + virBufferVSprintf(&buf, ",script=%s", + net->data.ethernet.script); + if (net->hostnet_name) + virBufferVSprintf(&buf, ",id=%s", + net->hostnet_name); + if (virBufferError(&buf)) { + virBufferFreeAndReset(&buf); + virReportOOMError(conn); + return -1; + } + + *str = virBufferContentAndReset(&buf); + } + break; + + case VIR_DOMAIN_NET_TYPE_CLIENT: + case VIR_DOMAIN_NET_TYPE_SERVER: + case VIR_DOMAIN_NET_TYPE_MCAST: + { + const char *mode = NULL; + + switch (net->type) { + case VIR_DOMAIN_NET_TYPE_CLIENT: + mode = "connect"; + break; + case VIR_DOMAIN_NET_TYPE_SERVER: + mode = "listen"; + break; + case VIR_DOMAIN_NET_TYPE_MCAST: + mode = "mcast"; + break; + } + + if (virAsprintf(str, "socket,%s=%s:%d,id=%s", + mode, + net->data.socket.address, + net->data.socket.port, + net->hostnet_name) < 0) { + virReportOOMError(conn); + return -1; + } + } + break; + + case VIR_DOMAIN_NET_TYPE_USER: + default: + if (virAsprintf(str, "user,id=%s", + net->hostnet_name) < 0) { + virReportOOMError(conn); + return -1; + } + break; + } + + return 0; +} + + static char *qemuBuildWatchdogDevStr(virDomainWatchdogDefPtr dev) { virBuffer buf = VIR_BUFFER_INITIALIZER; @@ -2961,27 +3080,10 @@ int qemudBuildCommandLine(virConnectPtr conn, for (i = 0 ; i < def->nnets ; i++) { virDomainNetDefPtr net = def->nets[i]; char *nic, *host; - char *tapfd_name = NULL; + char tapfd_name[50]; net->vlan = i; - ADD_ARG_SPACE; - if ((qemuCmdFlags & QEMUD_CMD_FLAG_NET_NAME) && - !(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) && - qemuAssignNetNames(def, net) < 0) - goto no_memory; - - if (qemuBuildNicStr(conn, net, "nic,", net->vlan, &nic) < 0) - goto error; - - if ((qargv[qargc++] = strdup("-net")) == NULL) { - VIR_FREE(nic); - goto no_memory; - } - ADD_ARG(nic); - - - ADD_ARG_SPACE; if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK || net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) { int tapfd = qemudNetworkIfaceConnect(conn, driver, net, qemuCmdFlags); @@ -2995,23 +3097,38 @@ int qemudBuildCommandLine(virConnectPtr conn, (*tapfds)[(*ntapfds)++] = tapfd; - if (virAsprintf(&tapfd_name, "%d", tapfd) < 0) + if (snprintf(tapfd_name, sizeof(tapfd_name), "%d", tapfd) >= sizeof(tapfd_name)) goto no_memory; } - if (qemuBuildHostNetStr(conn, net, ',', - net->vlan, tapfd_name, &host) < 0) { - VIR_FREE(tapfd_name); - goto error; + if ((qemuCmdFlags & QEMUD_CMD_FLAG_NET_NAME) && + !(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) { + if (qemuAssignNetNames(def, net) < 0) + goto no_memory; } - if ((qargv[qargc++] = strdup("-net")) == NULL) { - VIR_FREE(host); - goto no_memory; - } - ADD_ARG(host); + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { + ADD_ARG_LIT("-netdev"); + if (qemuBuildNetDevStr(conn, net, tapfd_name, &host) < 0) + goto error; + ADD_ARG(host); - VIR_FREE(tapfd_name); + ADD_ARG_LIT("-device"); + if (!(nic = qemuBuildNicDevStr(net))) + goto error; + ADD_ARG(nic); + } else { + ADD_ARG_LIT("-net"); + if (qemuBuildNicStr(conn, net, "nic,", net->vlan, &nic) < 0) + goto error; + ADD_ARG(nic); + + ADD_ARG_LIT("-net"); + if (qemuBuildHostNetStr(conn, net, ',', + net->vlan, tapfd_name, &host) < 0) + goto error; + ADD_ARG(host); + } } } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args new file mode 100644 index 0000000..2b5e856 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -netdev user,id=netdev0 -device virtio-net-pci,netdev=netdev0,id=virtio-nic0,mac=00:11:22:33:44:55 -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.xml new file mode 100644 index 0000000..5d34bd4 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.xml @@ -0,0 +1,26 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219200</memory> + <currentMemory>219200</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + </disk> + <interface type='user'> + <mac address='00:11:22:33:44:55'/> + <model type='virtio'/> + </interface> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 55e7d58..645f6b4 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -260,6 +260,7 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_UUID); DO_TEST("net-user", 0); DO_TEST("net-virtio", 0); + DO_TEST("net-virtio-device", QEMUD_CMD_FLAG_DEVICE); DO_TEST("net-eth", 0); DO_TEST("net-eth-ifname", 0); DO_TEST("net-eth-names", QEMUD_CMD_FLAG_NET_NAME); -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:21PM +0000, Daniel P. Berrange wrote:
The current syntax uses a pair of args
-net nic,macaddr=52:54:00:56:6c:55,vlan=3,model=pcnet,name=pcnet.0 -net user,vlan=3,name=user.0
The new syntax does not need the vlan craziness anymore, and so has a simplified pair of args
-netdev user,id=user.0 -device pcnet,netdev=user.0,id=pcnet.0,mac=52:54:00:56:6c:55,addr=<PCI SLOT> --- src/qemu/qemu_conf.c | 175 ++++++++++++++++---- .../qemuxml2argv-net-virtio-device.args | 1 + .../qemuxml2argv-net-virtio-device.xml | 26 +++ tests/qemuxml2argvtest.c | 1 + 4 files changed, 174 insertions(+), 29 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.xml
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 8b8455d..709c3f4 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1488,6 +1488,8 @@ qemuAssignDeviceAliases(virDomainDefPtr def) if (virAsprintf(&def->nets[i]->info.alias, "nic%d", i) < 0) goto no_memory; } + if (virAsprintf(&def->nets[i]->hostnet_name, "netdev%d", i) < 0) + goto no_memory; }
for (i = 0; i < def->nsounds ; i++) { @@ -2021,6 +2023,41 @@ qemuBuildNicStr(virConnectPtr conn, return 0; }
+static char * +qemuBuildNicDevStr(virDomainNetDefPtr net) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + const char *nic; + + if (!net->model) { + nic = "rtl8139"; + } else if (STREQ(net->model, "virtio")) { + nic = "virtio-net-pci"; + } else { + nic = net->model; + } + + virBufferVSprintf(&buf, "%s,netdev=%s", nic, net->hostnet_name); + virBufferVSprintf(&buf, ",id=%s", net->info.alias); + virBufferVSprintf(&buf, ",mac=%02x:%02x:%02x:%02x:%02x:%02x", + net->mac[0], net->mac[1], + net->mac[2], net->mac[3], + net->mac[4], net->mac[5]); + if (qemuBuildDeviceAddressStr(&buf, &net->info) < 0) + goto error; + + if (virBufferError(&buf)) { + virReportOOMError(NULL); + goto error; + } + + return virBufferContentAndReset(&buf); + +error: + virBufferFreeAndReset(&buf); + return NULL; +} + int qemuBuildHostNetStr(virConnectPtr conn, virDomainNetDefPtr net, @@ -2118,6 +2155,88 @@ qemuBuildHostNetStr(virConnectPtr conn, }
+static int +qemuBuildNetDevStr(virConnectPtr conn, + virDomainNetDefPtr net, + const char *tapfd, + char **str) +{ + switch (net->type) { + case VIR_DOMAIN_NET_TYPE_NETWORK: + case VIR_DOMAIN_NET_TYPE_BRIDGE: + if (virAsprintf(str, "tap,fd=%s,id=%s", + tapfd, net->hostnet_name) < 0) { + virReportOOMError(conn); + return -1; + } + break; + + case VIR_DOMAIN_NET_TYPE_ETHERNET: + { + virBuffer buf = VIR_BUFFER_INITIALIZER; + + virBufferAddLit(&buf, "tap"); + if (net->ifname) + virBufferVSprintf(&buf, ",ifname=%s", net->ifname); + if (net->data.ethernet.script) + virBufferVSprintf(&buf, ",script=%s", + net->data.ethernet.script); + if (net->hostnet_name) + virBufferVSprintf(&buf, ",id=%s", + net->hostnet_name); + if (virBufferError(&buf)) { + virBufferFreeAndReset(&buf); + virReportOOMError(conn); + return -1; + } + + *str = virBufferContentAndReset(&buf); + } + break; + + case VIR_DOMAIN_NET_TYPE_CLIENT: + case VIR_DOMAIN_NET_TYPE_SERVER: + case VIR_DOMAIN_NET_TYPE_MCAST: + { + const char *mode = NULL; + + switch (net->type) { + case VIR_DOMAIN_NET_TYPE_CLIENT: + mode = "connect"; + break; + case VIR_DOMAIN_NET_TYPE_SERVER: + mode = "listen"; + break; + case VIR_DOMAIN_NET_TYPE_MCAST: + mode = "mcast"; + break; + } + + if (virAsprintf(str, "socket,%s=%s:%d,id=%s", + mode, + net->data.socket.address, + net->data.socket.port, + net->hostnet_name) < 0) { + virReportOOMError(conn); + return -1; + } + } + break; + + case VIR_DOMAIN_NET_TYPE_USER: + default: + if (virAsprintf(str, "user,id=%s", + net->hostnet_name) < 0) { + virReportOOMError(conn); + return -1; + } + break; + } + + return 0; +} + + static char *qemuBuildWatchdogDevStr(virDomainWatchdogDefPtr dev) { virBuffer buf = VIR_BUFFER_INITIALIZER; @@ -2961,27 +3080,10 @@ int qemudBuildCommandLine(virConnectPtr conn, for (i = 0 ; i < def->nnets ; i++) { virDomainNetDefPtr net = def->nets[i]; char *nic, *host; - char *tapfd_name = NULL; + char tapfd_name[50];
net->vlan = i;
- ADD_ARG_SPACE; - if ((qemuCmdFlags & QEMUD_CMD_FLAG_NET_NAME) && - !(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) && - qemuAssignNetNames(def, net) < 0) - goto no_memory; - - if (qemuBuildNicStr(conn, net, "nic,", net->vlan, &nic) < 0) - goto error; - - if ((qargv[qargc++] = strdup("-net")) == NULL) { - VIR_FREE(nic); - goto no_memory; - } - ADD_ARG(nic); - - - ADD_ARG_SPACE; if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK || net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) { int tapfd = qemudNetworkIfaceConnect(conn, driver, net, qemuCmdFlags); @@ -2995,23 +3097,38 @@ int qemudBuildCommandLine(virConnectPtr conn,
(*tapfds)[(*ntapfds)++] = tapfd;
- if (virAsprintf(&tapfd_name, "%d", tapfd) < 0) + if (snprintf(tapfd_name, sizeof(tapfd_name), "%d", tapfd) >= sizeof(tapfd_name)) goto no_memory; }
- if (qemuBuildHostNetStr(conn, net, ',', - net->vlan, tapfd_name, &host) < 0) { - VIR_FREE(tapfd_name); - goto error; + if ((qemuCmdFlags & QEMUD_CMD_FLAG_NET_NAME) && + !(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) { + if (qemuAssignNetNames(def, net) < 0) + goto no_memory; }
- if ((qargv[qargc++] = strdup("-net")) == NULL) { - VIR_FREE(host); - goto no_memory; - } - ADD_ARG(host); + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { + ADD_ARG_LIT("-netdev"); + if (qemuBuildNetDevStr(conn, net, tapfd_name, &host) < 0) + goto error; + ADD_ARG(host);
- VIR_FREE(tapfd_name); + ADD_ARG_LIT("-device"); + if (!(nic = qemuBuildNicDevStr(net))) + goto error; + ADD_ARG(nic); + } else { + ADD_ARG_LIT("-net"); + if (qemuBuildNicStr(conn, net, "nic,", net->vlan, &nic) < 0) + goto error; + ADD_ARG(nic); + + ADD_ARG_LIT("-net"); + if (qemuBuildHostNetStr(conn, net, ',', + net->vlan, tapfd_name, &host) < 0) + goto error; + ADD_ARG(host); + } } }
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args new file mode 100644 index 0000000..2b5e856 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -netdev user,id=netdev0 -device virtio-net-pci,netdev=netdev0,id=virtio-nic0,mac=00:11:22:33:44:55 -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.xml new file mode 100644 index 0000000..5d34bd4 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.xml @@ -0,0 +1,26 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219200</memory> + <currentMemory>219200</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + </disk> + <interface type='user'> + <mac address='00:11:22:33:44:55'/> + <model type='virtio'/> + </interface> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 55e7d58..645f6b4 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -260,6 +260,7 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_UUID); DO_TEST("net-user", 0); DO_TEST("net-virtio", 0); + DO_TEST("net-virtio-device", QEMUD_CMD_FLAG_DEVICE); DO_TEST("net-eth", 0); DO_TEST("net-eth-ifname", 0); DO_TEST("net-eth-names", QEMUD_CMD_FLAG_NET_NAME);
ACK, separating the functions looks really better too Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

The previous syntax was severely limited in its options -usbdevice disk:/home/berrange/output.img The new syntax is the same as for other disk types -drive file=/home/berrange/output.img,if=none,id=usb-1,index=1 -device usb-storage,drive=usb-1 Again, the index= arg is wrong here, and will be removed in a later merge --- src/qemu/qemu_conf.c | 9 +++++- .../qemuxml2argv-disk-usb-device.args | 1 + .../qemuxml2argv-disk-usb-device.xml | 26 ++++++++++++++++++++ tests/qemuxml2argvtest.c | 1 + 4 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device.xml diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 709c3f4..53866eb 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1945,7 +1945,9 @@ qemuBuildDriveDevStr(virConnectPtr conn, virBufferAddLit(&opt, "virtio-blk-pci"); qemuBuildDeviceAddressStr(&opt, &disk->info); break; - + case VIR_DOMAIN_DISK_BUS_USB: + virBufferAddLit(&opt, "usb-storage"); + break; default: qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("unsupported disk bus '%s' with device setup"), bus); @@ -2947,7 +2949,10 @@ int qemudBuildCommandLine(virConnectPtr conn, virDomainDiskDefPtr disk = def->disks[i]; int withDeviceArg = 0; - if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) { + /* Unless we have -device, then USB disks need special + handling */ + if ((disk->bus == VIR_DOMAIN_DISK_BUS_USB) && + !(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) { if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) { ADD_USBDISK(disk->src); } else { diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device.args new file mode 100644 index 0000000..d12d61c --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=none,id=drive-ide0-0-0 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 -drive file=/tmp/usbdisk.img,if=none,id=drive-usb-disk0 -device usb-storage,drive=drive-usb-disk0,id=usb-disk0 -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device.xml new file mode 100644 index 0000000..d59e1c0 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device.xml @@ -0,0 +1,26 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219200</memory> + <currentMemory>219200</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + </disk> + <disk type='file' device='disk'> + <source file='/tmp/usbdisk.img'/> + <target dev='sda' bus='usb'/> + </disk> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 645f6b4..8c88a79 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -235,6 +235,7 @@ mymain(int argc, char **argv) DO_TEST("disk-drive-cache-v2-none", QEMUD_CMD_FLAG_DRIVE | QEMUD_CMD_FLAG_DRIVE_CACHE_V2 | QEMUD_CMD_FLAG_DRIVE_FORMAT); DO_TEST("disk-usb", 0); + DO_TEST("disk-usb-device", QEMUD_CMD_FLAG_DRIVE | QEMUD_CMD_FLAG_DEVICE); DO_TEST("graphics-vnc", 0); driver.vncSASL = 1; -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:22PM +0000, Daniel P. Berrange wrote:
The previous syntax was severely limited in its options
-usbdevice disk:/home/berrange/output.img
The new syntax is the same as for other disk types
-drive file=/home/berrange/output.img,if=none,id=usb-1,index=1 -device usb-storage,drive=usb-1
Again, the index= arg is wrong here, and will be removed in a later merge
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

The old syntax was -usbdevice host:PRODUCT:VENDOR Or -usbdevice host:BUS.DEV The new syntax is -device usb-host,product=PRODUCT,vendor=VENDOR Or -device usb-host,hostbus=BUS,hostaddr=DEV --- src/qemu/qemu_conf.c | 32 ++++++++++++++----- .../qemuxml2argv-hostdev-usb-address-device.args | 1 + .../qemuxml2argv-hostdev-usb-address-device.xml | 27 ++++++++++++++++ tests/qemuxml2argvtest.c | 1 + 4 files changed, 52 insertions(+), 9 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.xml diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 53866eb..1ea61a9 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -3510,22 +3510,36 @@ int qemudBuildCommandLine(virConnectPtr conn, /* USB */ if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { - if(hostdev->source.subsys.u.usb.vendor) { - ret = virAsprintf(&usbdev, "host:%.4x:%.4x", - hostdev->source.subsys.u.usb.vendor, - hostdev->source.subsys.u.usb.product); + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { + ADD_ARG_LIT("-device"); + if (hostdev->source.subsys.u.usb.vendor) { + ret = virAsprintf(&usbdev, "usb-host,vendor=%.4x,product=%.4x,id=%s", + hostdev->source.subsys.u.usb.vendor, + hostdev->source.subsys.u.usb.product, + hostdev->info.alias); + } else { + ret = virAsprintf(&usbdev, "usb-host,hostbus=%.3d,hostaddr=%.3d,id=%s", + hostdev->source.subsys.u.usb.bus, + hostdev->source.subsys.u.usb.device, + hostdev->info.alias); + } } else { + ADD_ARG_LIT("-usbdevice"); + if (hostdev->source.subsys.u.usb.vendor) { + ret = virAsprintf(&usbdev, "host:%.4x:%.4x", + hostdev->source.subsys.u.usb.vendor, + hostdev->source.subsys.u.usb.product); + } else { ret = virAsprintf(&usbdev, "host:%.3d.%.3d", - hostdev->source.subsys.u.usb.bus, - hostdev->source.subsys.u.usb.device); + hostdev->source.subsys.u.usb.bus, + hostdev->source.subsys.u.usb.device); + } } if (ret < 0) goto error; - ADD_ARG_LIT("-usbdevice"); - ADD_ARG_LIT(usbdev); - VIR_FREE(usbdev); + ADD_ARG(usbdev); } /* PCI */ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.args b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.args new file mode 100644 index 0000000..70f48c4 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -device usb-host,hostbus=014,hostaddr=006,id=hostusb0 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.xml new file mode 100644 index 0000000..61bb2a2 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.xml @@ -0,0 +1,27 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219200</memory> + <currentMemory>219200</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + </disk> + <hostdev mode='subsystem' type='usb' managed='no'> + <source> + <address bus='14' device='6'/> + </source> + </hostdev> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 8c88a79..2042e2a 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -299,6 +299,7 @@ mymain(int argc, char **argv) DO_TEST("hostdev-usb-product", 0); DO_TEST("hostdev-usb-address", 0); + DO_TEST("hostdev-usb-address-device", QEMUD_CMD_FLAG_DEVICE); DO_TEST("hostdev-pci-address", QEMUD_CMD_FLAG_PCIDEVICE); DO_TEST_FULL("restore-v1", QEMUD_CMD_FLAG_MIGRATE_KVM_STDIO, "stdio"); -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:23PM +0000, Daniel P. Berrange wrote:
The old syntax was
-usbdevice host:PRODUCT:VENDOR
Or
-usbdevice host:BUS.DEV
The new syntax is
-device usb-host,product=PRODUCT,vendor=VENDOR
Or
-device usb-host,hostbus=BUS,hostaddr=DEV --- src/qemu/qemu_conf.c | 32 ++++++++++++++----- .../qemuxml2argv-hostdev-usb-address-device.args | 1 + .../qemuxml2argv-hostdev-usb-address-device.xml | 27 ++++++++++++++++ tests/qemuxml2argvtest.c | 1 + 4 files changed, 52 insertions(+), 9 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.xml
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

--- src/qemu/qemu_conf.c | 34 ++++++++++++++++++++++++++++++++-- 1 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 1ea61a9..3b39a91 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -2268,6 +2268,28 @@ error: } +static char *qemuBuildUSBInputDevStr(virDomainInputDefPtr dev) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + + virBufferVSprintf(&buf, "%s", + dev->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ? + "usb-mouse" : "usb-tablet"); + virBufferVSprintf(&buf, ",id=%s", dev->info.alias); + + if (virBufferError(&buf)) { + virReportOOMError(NULL); + goto error; + } + + return virBufferContentAndReset(&buf); + +error: + virBufferFreeAndReset(&buf); + return NULL; +} + + static char * qemuBuildSoundDevStr(virDomainSoundDefPtr sound) { @@ -3273,8 +3295,16 @@ int qemudBuildCommandLine(virConnectPtr conn, virDomainInputDefPtr input = def->inputs[i]; if (input->bus == VIR_DOMAIN_INPUT_BUS_USB) { - ADD_ARG_LIT("-usbdevice"); - ADD_ARG_LIT(input->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ? "mouse" : "tablet"); + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { + char *optstr; + ADD_ARG_LIT("-device"); + if (!(optstr = qemuBuildUSBInputDevStr(input))) + goto error; + ADD_ARG(optstr); + } else { + ADD_ARG_LIT("-usbdevice"); + ADD_ARG_LIT(input->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ? "mouse" : "tablet"); + } } } -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:24PM +0000, Daniel P. Berrange wrote:
--- src/qemu/qemu_conf.c | 34 ++++++++++++++++++++++++++++++++-- 1 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 1ea61a9..3b39a91 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -2268,6 +2268,28 @@ error: }
+static char *qemuBuildUSBInputDevStr(virDomainInputDefPtr dev) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + + virBufferVSprintf(&buf, "%s", + dev->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ? + "usb-mouse" : "usb-tablet"); + virBufferVSprintf(&buf, ",id=%s", dev->info.alias); + + if (virBufferError(&buf)) { + virReportOOMError(NULL); + goto error; + } + + return virBufferContentAndReset(&buf); + +error: + virBufferFreeAndReset(&buf); + return NULL; +} + + static char * qemuBuildSoundDevStr(virDomainSoundDefPtr sound) { @@ -3273,8 +3295,16 @@ int qemudBuildCommandLine(virConnectPtr conn, virDomainInputDefPtr input = def->inputs[i];
if (input->bus == VIR_DOMAIN_INPUT_BUS_USB) { - ADD_ARG_LIT("-usbdevice"); - ADD_ARG_LIT(input->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ? "mouse" : "tablet"); + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { + char *optstr; + ADD_ARG_LIT("-device"); + if (!(optstr = qemuBuildUSBInputDevStr(input))) + goto error; + ADD_ARG(optstr); + } else { + ADD_ARG_LIT("-usbdevice"); + ADD_ARG_LIT(input->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ? "mouse" : "tablet"); + } } }
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

The old syntax is -pcidevice host=BUS:SLOT:FUNCTION The new syntax is -device pci-assign,host=BUS:SLOT:FUNCTION,addr=<PCI SLOT>,id=host0 --- src/qemu/qemu_conf.c | 51 +++++++++++++++----- .../qemuxml2argv-hostdev-pci-address-device.args | 1 + .../qemuxml2argv-hostdev-pci-address-device.xml | 27 ++++++++++ tests/qemuxml2argvtest.c | 1 + 4 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.xml diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 3b39a91..a09fb62 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -2326,6 +2326,32 @@ error: } +static char * +qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + + virBufferAddLit(&buf, "pci-assign"); + virBufferVSprintf(&buf, ",host=%.2x:%.2x.%.1x", + dev->source.subsys.u.pci.bus, + dev->source.subsys.u.pci.slot, + dev->source.subsys.u.pci.function); + virBufferVSprintf(&buf, ",id=%s", dev->info.alias); + if (qemuBuildDeviceAddressStr(&buf, &dev->info) < 0) + goto error; + + if (virBufferError(&buf)) { + virReportOOMError(NULL); + goto error; + } + + return virBufferContentAndReset(&buf); + +error: + virBufferFreeAndReset(&buf); + return NULL; +} + /* This function outputs a -chardev command line option which describes only the * host side of the character device */ static void qemudBuildCommandLineChrDevChardevStr(virDomainChrDefPtr dev, @@ -3575,22 +3601,23 @@ int qemudBuildCommandLine(virConnectPtr conn, /* PCI */ if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { - if (!(qemuCmdFlags & QEMUD_CMD_FLAG_PCIDEVICE)) { + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { + ADD_ARG_LIT("-device"); + if (!(pcidev = qemuBuildPCIHostdevDevStr(hostdev))) + goto error; + } else if (qemuCmdFlags & QEMUD_CMD_FLAG_PCIDEVICE) { + ADD_ARG_LIT("-pcidevice"); + if (virAsprintf(&pcidev, "host=%.2x:%.2x.%.1x", + hostdev->source.subsys.u.pci.bus, + hostdev->source.subsys.u.pci.slot, + hostdev->source.subsys.u.pci.function) < 0) + goto no_memory; + } else { qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT, "%s", _("PCI device assignment is not supported by this version of qemu")); goto error; } - ret = virAsprintf(&pcidev, "host=%.2x:%.2x.%.1x", - hostdev->source.subsys.u.pci.bus, - hostdev->source.subsys.u.pci.slot, - hostdev->source.subsys.u.pci.function); - if (ret < 0) { - pcidev = NULL; - goto no_memory; - } - ADD_ARG_LIT("-pcidevice"); - ADD_ARG_LIT(pcidev); - VIR_FREE(pcidev); + ADD_ARG(pcidev); } } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args new file mode 100644 index 0000000..f1865ee --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest2 -usb -device pci-assign,host=06:12.5,id=hostpci0 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.xml new file mode 100644 index 0000000..ac5ad47 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.xml @@ -0,0 +1,27 @@ +<domain type='qemu'> + <name>QEMUGuest2</name> + <uuid>c7a5fdbd-edaf-9466-926a-d65c16db1809</uuid> + <memory>219200</memory> + <currentMemory>219200</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='hda' bus='ide'/> + </disk> + <hostdev mode='subsystem' type='pci' managed='yes'> + <source> + <address domain='0x0000' bus='0x06' slot='0x12' function='0x5'/> + </source> + </hostdev> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 2042e2a..2a2387e 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -301,6 +301,7 @@ mymain(int argc, char **argv) DO_TEST("hostdev-usb-address", 0); DO_TEST("hostdev-usb-address-device", QEMUD_CMD_FLAG_DEVICE); DO_TEST("hostdev-pci-address", QEMUD_CMD_FLAG_PCIDEVICE); + DO_TEST("hostdev-pci-address-device", QEMUD_CMD_FLAG_PCIDEVICE|QEMUD_CMD_FLAG_DEVICE); DO_TEST_FULL("restore-v1", QEMUD_CMD_FLAG_MIGRATE_KVM_STDIO, "stdio"); DO_TEST_FULL("restore-v2", QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC, "stdio"); -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:25PM +0000, Daniel P. Berrange wrote:
The old syntax is
-pcidevice host=BUS:SLOT:FUNCTION
The new syntax is
-device pci-assign,host=BUS:SLOT:FUNCTION,addr=<PCI SLOT>,id=host0 --- src/qemu/qemu_conf.c | 51 +++++++++++++++----- .../qemuxml2argv-hostdev-pci-address-device.args | 1 + .../qemuxml2argv-hostdev-pci-address-device.xml | 27 ++++++++++ tests/qemuxml2argvtest.c | 1 + 4 files changed, 68 insertions(+), 12 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.xml
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

The old syntax was -chardev SOMECONFIG -nic user,guestfwd=tcp:IP:PORT-chardev:CHARDEV The new syntax is -chardev SOMECONFIG -netdev user,guestfwd=tcp:IP:PORT,chardev=ID,id=user-ID --- src/qemu/qemu_conf.c | 11 ++++++----- .../qemuxml2argv-channel-guestfwd.args | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index a09fb62..9cd53f9 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -3283,9 +3283,10 @@ int qemudBuildCommandLine(virConnectPtr conn, switch(channel->targetType) { case VIR_DOMAIN_CHR_TARGET_TYPE_GUESTFWD: - if (!(qemuCmdFlags & QEMUD_CMD_FLAG_CHARDEV)) { + if (!(qemuCmdFlags & QEMUD_CMD_FLAG_CHARDEV) || + !(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) { qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT, - "%s", _("guestfwd requires QEMU to support -chardev")); + "%s", _("guestfwd requires QEMU to support -chardev & -device")); goto error; } @@ -3301,8 +3302,9 @@ int qemudBuildCommandLine(virConnectPtr conn, const char *addr = virSocketFormatAddr(channel->target.addr); int port = virSocketGetPort(channel->target.addr); - virBufferVSprintf(&buf, "user,guestfwd=tcp:%s:%i-chardev:%s", - addr, port, channel->info.alias); + ADD_ARG_LIT("-netdev"); + virBufferVSprintf(&buf, "user,guestfwd=tcp:%s:%i,chardev=%s,id=user-%s", + addr, port, channel->info.alias, channel->info.alias); VIR_FREE(addr); @@ -3311,7 +3313,6 @@ int qemudBuildCommandLine(virConnectPtr conn, goto no_memory; } - ADD_ARG_LIT("-net"); ADD_ARG(virBufferContentAndReset(&buf)); } } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args index c3148df..e93e934 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev pipe,id=channel0,path=/tmp/guestfwd -net user,guestfwd=tcp:10.0.2.1:4600-chardev:channel0 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev pipe,id=channel0,path=/tmp/guestfwd -netdev user,guestfwd=tcp:10.0.2.1:4600,chardev=channel0,id=user-channel0 -usb -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:26PM +0000, Daniel P. Berrange wrote:
The old syntax was
-chardev SOMECONFIG -nic user,guestfwd=tcp:IP:PORT-chardev:CHARDEV
The new syntax is
-chardev SOMECONFIG -netdev user,guestfwd=tcp:IP:PORT,chardev=ID,id=user-ID --- src/qemu/qemu_conf.c | 11 ++++++----- .../qemuxml2argv-channel-guestfwd.args | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index a09fb62..9cd53f9 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -3283,9 +3283,10 @@ int qemudBuildCommandLine(virConnectPtr conn,
switch(channel->targetType) { case VIR_DOMAIN_CHR_TARGET_TYPE_GUESTFWD: - if (!(qemuCmdFlags & QEMUD_CMD_FLAG_CHARDEV)) { + if (!(qemuCmdFlags & QEMUD_CMD_FLAG_CHARDEV) || + !(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) { qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT, - "%s", _("guestfwd requires QEMU to support -chardev")); + "%s", _("guestfwd requires QEMU to support -chardev & -device")); goto error; }
@@ -3301,8 +3302,9 @@ int qemudBuildCommandLine(virConnectPtr conn, const char *addr = virSocketFormatAddr(channel->target.addr); int port = virSocketGetPort(channel->target.addr);
- virBufferVSprintf(&buf, "user,guestfwd=tcp:%s:%i-chardev:%s", - addr, port, channel->info.alias); + ADD_ARG_LIT("-netdev"); + virBufferVSprintf(&buf, "user,guestfwd=tcp:%s:%i,chardev=%s,id=user-%s", + addr, port, channel->info.alias, channel->info.alias);
VIR_FREE(addr);
@@ -3311,7 +3313,6 @@ int qemudBuildCommandLine(virConnectPtr conn, goto no_memory; }
- ADD_ARG_LIT("-net"); ADD_ARG(virBufferContentAndReset(&buf)); } } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args index c3148df..e93e934 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev pipe,id=channel0,path=/tmp/guestfwd -net user,guestfwd=tcp:10.0.2.1:4600-chardev:channel0 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev pipe,id=channel0,path=/tmp/guestfwd -netdev user,guestfwd=tcp:10.0.2.1:4600,chardev=channel0,id=user-channel0 -usb -- 1.6.5.2
ACK Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Not all QEMU builds default to SDL graphics for their display. Newer QEMU now has an explicit -sdl flag, which we can use to explicitly request SDL intead of relying on the default. This protects libvirt against unexpected changes in graphics default * src/qemu/qemu_conf.c, src/qemu/qemu_conf.h: Probe for -sdl flag and use it if it is found * tests/qemuhelptest.c: Add SDL flag to tests --- src/qemu/qemu_conf.c | 8 ++++++++ src/qemu/qemu_conf.h | 1 + tests/qemuhelptest.c | 13 +++++++++---- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 9cd53f9..b87b170 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1117,6 +1117,8 @@ static unsigned int qemudComputeCmdFlags(const char *help, flags |= QEMUD_CMD_FLAG_BALLOON; if (strstr(help, "-device")) flags |= QEMUD_CMD_FLAG_DEVICE; + if (strstr(help, "-sdl")) + flags |= QEMUD_CMD_FLAG_SDL; if (version >= 9000) flags |= QEMUD_CMD_FLAG_VNC_COLON; @@ -3425,6 +3427,12 @@ int qemudBuildCommandLine(virConnectPtr conn, */ ADD_ENV_COPY("QEMU_AUDIO_DRV"); ADD_ENV_COPY("SDL_AUDIODRIVER"); + + /* New QEMU has this flag to let us explicitly ask for + * SDL graphics. This is better than relying on the + * default, since the default changes :-( */ + if (qemuCmdFlags & QEMUD_CMD_FLAG_SDL) + ADD_ARG_LIT("-sdl"); } if (def->nvideos) { diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 174d397..4a862d1 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -79,6 +79,7 @@ enum qemud_cmd_flags { QEMUD_CMD_FLAG_MONITOR_JSON = (1 << 24), /* JSON mode for monitor */ QEMUD_CMD_FLAG_BALLOON = (1 << 25), /* -balloon available */ QEMUD_CMD_FLAG_DEVICE = (1 << 26), /* Is the new -chardev arg available */ + QEMUD_CMD_FLAG_SDL = (1 << 27), /* Is the new -sdl arg available */ }; /* Main driver state */ diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c index c2d7942..5ae14a6 100644 --- a/tests/qemuhelptest.c +++ b/tests/qemuhelptest.c @@ -140,7 +140,8 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_DRIVE_SERIAL | QEMUD_CMD_FLAG_VGA | QEMUD_CMD_FLAG_0_10 | - QEMUD_CMD_FLAG_ENABLE_KVM, + QEMUD_CMD_FLAG_ENABLE_KVM | + QEMUD_CMD_FLAG_SDL, 10005, 0, 0); DO_TEST("qemu-kvm-0.10.5", QEMUD_CMD_FLAG_VNC_COLON | @@ -159,7 +160,8 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_VGA | QEMUD_CMD_FLAG_0_10 | QEMUD_CMD_FLAG_PCIDEVICE | - QEMUD_CMD_FLAG_MEM_PATH, + QEMUD_CMD_FLAG_MEM_PATH | + QEMUD_CMD_FLAG_SDL, 10005, 1, 0); DO_TEST("kvm-86", QEMUD_CMD_FLAG_VNC_COLON | @@ -177,7 +179,8 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_DRIVE_SERIAL | QEMUD_CMD_FLAG_VGA | QEMUD_CMD_FLAG_0_10 | - QEMUD_CMD_FLAG_PCIDEVICE, + QEMUD_CMD_FLAG_PCIDEVICE | + QEMUD_CMD_FLAG_SDL, 10050, 1, 0); DO_TEST("qemu-kvm-0.11.0-rc2", QEMUD_CMD_FLAG_VNC_COLON | @@ -198,7 +201,8 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_PCIDEVICE | QEMUD_CMD_FLAG_MEM_PATH | QEMUD_CMD_FLAG_ENABLE_KVM | - QEMUD_CMD_FLAG_BALLOON, + QEMUD_CMD_FLAG_BALLOON | + QEMUD_CMD_FLAG_SDL, 10092, 1, 0); DO_TEST("qemu-0.12.1", QEMUD_CMD_FLAG_VNC_COLON | @@ -214,6 +218,7 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_VGA | QEMUD_CMD_FLAG_0_10 | QEMUD_CMD_FLAG_ENABLE_KVM | + QEMUD_CMD_FLAG_SDL | QEMUD_CMD_FLAG_XEN_DOMID | QEMUD_CMD_FLAG_MIGRATE_QEMU_UNIX | QEMUD_CMD_FLAG_CHARDEV | -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:27PM +0000, Daniel P. Berrange wrote:
Not all QEMU builds default to SDL graphics for their display. Newer QEMU now has an explicit -sdl flag, which we can use to explicitly request SDL intead of relying on the default. This protects libvirt against unexpected changes in graphics default
if (def->nvideos) { diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 174d397..4a862d1 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -79,6 +79,7 @@ enum qemud_cmd_flags { QEMUD_CMD_FLAG_MONITOR_JSON = (1 << 24), /* JSON mode for monitor */ QEMUD_CMD_FLAG_BALLOON = (1 << 25), /* -balloon available */ QEMUD_CMD_FLAG_DEVICE = (1 << 26), /* Is the new -chardev arg available */ + QEMUD_CMD_FLAG_SDL = (1 << 27), /* Is the new -sdl arg available */ };
Aren't we getting close to the 32 options limits ? ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Fri, Jan 15, 2010 at 09:00:36PM +0100, Daniel Veillard wrote:
On Fri, Jan 08, 2010 at 05:23:27PM +0000, Daniel P. Berrange wrote:
Not all QEMU builds default to SDL graphics for their display. Newer QEMU now has an explicit -sdl flag, which we can use to explicitly request SDL intead of relying on the default. This protects libvirt against unexpected changes in graphics default
if (def->nvideos) { diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 174d397..4a862d1 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -79,6 +79,7 @@ enum qemud_cmd_flags { QEMUD_CMD_FLAG_MONITOR_JSON = (1 << 24), /* JSON mode for monitor */ QEMUD_CMD_FLAG_BALLOON = (1 << 25), /* -balloon available */ QEMUD_CMD_FLAG_DEVICE = (1 << 26), /* Is the new -chardev arg available */ + QEMUD_CMD_FLAG_SDL = (1 << 27), /* Is the new -sdl arg available */ };
Aren't we getting close to the 32 options limits ?
It doesn't really matter as we can trivially just make it an int64, or turn it into a plain enum, instead of bitflags. This isn't exposed in the API anywhere Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

QEMU always configures a VGA card. If no video card is included in the libvirt XML, it is neccessary to explicitly turn off the default using -vga none * src/qemu/qemu_conf.c: Pass -vga none if no video card is configured * tests/qemuargv2xmltest.c, tests/qemuxml2argvtest.c: Test for handling -vga none. * tests/qemuxml2argvdata/qemuxml2argv-nographics-vga.args, tests/qemuxml2argvdata/qemuxml2argv-nographics-vga.xml: Test data files --- src/qemu/qemu_conf.c | 25 +++++++++++++------ tests/qemuargv2xmltest.c | 1 + .../qemuxml2argv-nographics-vga.args | 1 + .../qemuxml2argv-nographics-vga.xml | 24 +++++++++++++++++++ tests/qemuxml2argvtest.c | 1 + 5 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-nographics-vga.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-nographics-vga.xml diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index b87b170..bb6e90f 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -89,8 +89,8 @@ VIR_ENUM_IMPL(qemuVideo, VIR_DOMAIN_VIDEO_TYPE_LAST, "std", "cirrus", "vmware", - NULL, /* no arg needed for xen */ - NULL /* don't support vbox */); + "", /* no arg needed for xen */ + "" /* don't support vbox */); #define PROC_MOUNT_BUF_LEN 255 @@ -3447,7 +3447,7 @@ int qemudBuildCommandLine(virConnectPtr conn, /* nothing - vga has no effect on Xen pvfb */ } else { const char *vgastr = qemuVideoTypeToString(def->videos[0]->type); - if (!vgastr) { + if (!vgastr || STREQ(vgastr, "")) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("video type %s is not supported with QEMU"), virDomainVideoTypeToString(def->videos[0]->type)); @@ -3480,6 +3480,13 @@ int qemudBuildCommandLine(virConnectPtr conn, goto error; } } + } else { + /* If we have -device, then we set -nodefault already */ + if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) && + (qemuCmdFlags & QEMUD_CMD_FLAG_VGA)) { + ADD_ARG_LIT("-vga"); + ADD_ARG_LIT("none"); + } } /* Add sound hardware */ @@ -5017,11 +5024,13 @@ virDomainDefPtr qemuParseCommandLine(virConnectPtr conn, video = VIR_DOMAIN_VIDEO_TYPE_VGA; } else if (STREQ(arg, "-vga")) { WANT_VALUE(); - video = qemuVideoTypeFromString(val); - if (video < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("unknown video adapter type '%s'"), val); - goto error; + if (STRNEQ(val, "none")) { + video = qemuVideoTypeFromString(val); + if (video < 0) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("unknown video adapter type '%s'"), val); + goto error; + } } } else if (STREQ(arg, "-cpu")) { WANT_VALUE(); diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c index 7f62bac..8326c57 100644 --- a/tests/qemuargv2xmltest.c +++ b/tests/qemuargv2xmltest.c @@ -185,6 +185,7 @@ mymain(int argc, char **argv) DO_TEST("graphics-sdl", 0); DO_TEST("graphics-sdl-fullscreen", 0); + DO_TEST("nographics-vga", QEMUD_CMD_FLAG_VGA); DO_TEST("input-usbmouse", 0); DO_TEST("input-usbtablet", 0); /* Can't rountrip xenner arch */ diff --git a/tests/qemuxml2argvdata/qemuxml2argv-nographics-vga.args b/tests/qemuxml2argvdata/qemuxml2argv-nographics-vga.args new file mode 100644 index 0000000..b8f10bb --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-nographics-vga.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb -vga none diff --git a/tests/qemuxml2argvdata/qemuxml2argv-nographics-vga.xml b/tests/qemuxml2argvdata/qemuxml2argv-nographics-vga.xml new file mode 100644 index 0000000..533ea59 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-nographics-vga.xml @@ -0,0 +1,24 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219200</memory> + <currentMemory>219200</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> + </disk> + <controller type='ide' index='0'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 2a2387e..41e5749 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -252,6 +252,7 @@ mymain(int argc, char **argv) DO_TEST("graphics-sdl", 0); DO_TEST("graphics-sdl-fullscreen", 0); + DO_TEST("nographics-vga", QEMUD_CMD_FLAG_VGA); DO_TEST("input-usbmouse", 0); DO_TEST("input-usbtablet", 0); DO_TEST("input-xen", QEMUD_CMD_FLAG_DOMID); -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:28PM +0000, Daniel P. Berrange wrote:
QEMU always configures a VGA card. If no video card is included in the libvirt XML, it is neccessary to explicitly turn off the default using -vga none
* src/qemu/qemu_conf.c: Pass -vga none if no video card is configured * tests/qemuargv2xmltest.c, tests/qemuxml2argvtest.c: Test for handling -vga none. * tests/qemuxml2argvdata/qemuxml2argv-nographics-vga.args, tests/qemuxml2argvdata/qemuxml2argv-nographics-vga.xml: Test data files --- src/qemu/qemu_conf.c | 25 +++++++++++++------ tests/qemuargv2xmltest.c | 1 + .../qemuxml2argv-nographics-vga.args | 1 + .../qemuxml2argv-nographics-vga.xml | 24 +++++++++++++++++++ tests/qemuxml2argvtest.c | 1 + 5 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-nographics-vga.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-nographics-vga.xml
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Instead of relying on QEMU to assign PCI addresses and then querying them with 'info pci', manually assign all PCI addresses before starting the guest. These addresses are not stable across reboots. That will come in a later patch NB, the PIIX3 (IDE, FDC, ISA-Bridge) will always have slot 1 and VGA will always have slot 2. We declare the Virtio Balloon gets slot 3, and then all remaining slots are for configured devices. * src/qemu/qemu_conf.c: If -device is supported, then assign all PCI addresses when building the command line * src/qemu/qemu_driver.c: Don't query monitor for PCI addresses if they have already been assigned * tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args, tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args, tests/qemuxml2argvdata/qemuxml2argv-sound-device.args, tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.args: Update to include PCI slot/bus information --- src/qemu/qemu_conf.c | 108 +++++++++++++++++++- src/qemu/qemu_driver.c | 13 ++- .../qemuxml2argv-hostdev-pci-address-device.args | 2 +- .../qemuxml2argv-net-virtio-device.args | 2 +- .../qemuxml2argv-sound-device.args | 2 +- .../qemuxml2argv-watchdog-device.args | 2 +- 6 files changed, 121 insertions(+), 8 deletions(-) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index bb6e90f..415e6da 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1547,6 +1547,108 @@ qemuAssignDeviceAliases(virDomainDefPtr def) } +static void +qemuAssignDevicePCISlot(virDomainDeviceInfoPtr info, + int slot) +{ + info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + info->addr.pci.domain = 0; + info->addr.pci.bus = 0; + info->addr.pci.slot = slot; + info->addr.pci.function = 0; +} + +static void +qemuAssignDevicePCISlots(virDomainDefPtr def) +{ + int i; + /* + * slot = 0 -> Host bridge + * slot = 1 -> PIIX3 (ISA bridge, IDE controller, something else unknown, USB controller) + * slot = 2 -> VGA + * slot = 3 -> VirtIO Balloon + */ + int nextslot = 4; + + for (i = 0; i < def->ndisks ; i++) { + if (def->disks[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + continue; + + /* Only VirtIO disks use PCI addrs */ + if (def->disks[i]->bus != VIR_DOMAIN_DISK_BUS_VIRTIO) + continue; + + qemuAssignDevicePCISlot(&def->disks[i]->info, nextslot++); + } + + for (i = 0; i < def->nnets ; i++) { + if (def->nets[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + continue; + qemuAssignDevicePCISlot(&def->nets[i]->info, nextslot++); + } + + for (i = 0; i < def->nsounds ; i++) { + if (def->sounds[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + continue; + /* Skip ISA sound card, and PCSPK */ + if (def->sounds[i]->model == VIR_DOMAIN_SOUND_MODEL_SB16 || + def->sounds[i]->model == VIR_DOMAIN_SOUND_MODEL_PCSPK) + continue; + + qemuAssignDevicePCISlot(&def->sounds[i]->info, nextslot++); + } + + for (i = 0; i < def->nhostdevs ; i++) { + if (def->hostdevs[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + continue; + if (def->hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || + def->hostdevs[i]->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) + continue; + + qemuAssignDevicePCISlot(&def->hostdevs[i]->info, nextslot++); + } + for (i = 0; i < def->nvideos ; i++) { + /* First VGA is hardcoded slot=2 */ + if (i == 0) + qemuAssignDevicePCISlot(&def->videos[i]->info, 2); + else + qemuAssignDevicePCISlot(&def->videos[i]->info, nextslot++); + } + for (i = 0; i < def->ncontrollers ; i++) { + if (def->controllers[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + continue; + /* FDC lives behind the ISA bridge */ + if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_FDC) + continue; + + /* First IDE controller lives on the PIIX3 at slot=1, function=1 */ + if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_IDE && + def->controllers[i]->idx == 0) { + qemuAssignDevicePCISlot(&def->controllers[i]->info, 1); + def->controllers[i]->info.addr.pci.function = 1; + } else { + qemuAssignDevicePCISlot(&def->controllers[i]->info, nextslot++); + } + } + for (i = 0; i < def->ninputs ; i++) { + /* Nada - none are PCI based (yet) */ + } + for (i = 0; i < def->nparallels ; i++) { + /* Nada - none are PCI based (yet) */ + } + for (i = 0; i < def->nserials ; i++) { + /* Nada - none are PCI based (yet) */ + } + for (i = 0; i < def->nchannels ; i++) { + /* Nada - none are PCI based (yet) */ + /* XXX virtio-serial will need one */ + } + if (def->watchdog) { + qemuAssignDevicePCISlot(&def->watchdog->info, nextslot++); + } +} + + static char *qemuDiskLegacyName(const virDomainDiskDefPtr disk) { char *devname; @@ -2609,10 +2711,12 @@ int qemudBuildCommandLine(virConnectPtr conn, uname_normalize(&ut); - if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { qemuAssignDeviceAliases(def); - else + qemuAssignDevicePCISlots(def); + } else { qemuAssignDiskAliases(def, qemuCmdFlags); + } virUUIDFormat(def->uuid, uuid); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 6aabe3e..3d33da3 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2697,6 +2697,11 @@ qemuPrepareMonitorChr(virConnectPtr conn, monConfig->type = VIR_DOMAIN_CHR_TYPE_UNIX; monConfig->data.nix.listen = 1; + if (!(monConfig->info.alias = strdup("monitor"))) { + virReportOOMError(conn); + return -1; + } + if (virAsprintf(&monConfig->data.nix.path, "%s/%s.monitor", driver->libDir, vm) < 0) { virReportOOMError(conn); @@ -2920,8 +2925,12 @@ static int qemudStartVMDaemon(virConnectPtr conn, if (qemuInitPasswords(driver, vm) < 0) goto abort; - if (qemuInitPCIAddresses(driver, vm) < 0) - goto abort; + /* If we have -device, then addresses are assigned explicitly. + * If not, then we have to detect dynamic ones here */ + if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) { + if (qemuInitPCIAddresses(driver, vm) < 0) + goto abort; + } qemuDomainObjEnterMonitorWithDriver(driver, vm); if (qemuMonitorSetBalloon(priv->mon, vm->def->memory) < 0) { diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args index f1865ee..611950a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest2 -usb -device pci-assign,host=06:12.5,id=hostpci0 +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest2 -usb -device pci-assign,host=06:12.5,id=hostpci0,addr=4 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args index 2b5e856..9324047 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -netdev user,id=netdev0 -device virtio-net-pci,netdev=netdev0,id=virtio-nic0,mac=00:11:22:33:44:55 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -netdev user,id=netdev0 -device virtio-net-pci,netdev=netdev0,id=virtio-nic0,mac=00:11:22:33:44:55,addr=4 -usb diff --git a/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args b/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args index 31ac0ee..b9adec6 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -soundhw pcspk -device ES1370,id=sound1 -device sb16,id=sound2 -device AC97,id=sound3 +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -soundhw pcspk -device ES1370,id=sound1,addr=4 -device sb16,id=sound2 -device AC97,id=sound3,addr=5 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.args b/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.args index 5f3a428..f05111c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -device ib700,id=watchdog0 -watchdog-action poweroff +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -device ib700,id=watchdog0,addr=4 -watchdog-action poweroff -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:29PM +0000, Daniel P. Berrange wrote:
Instead of relying on QEMU to assign PCI addresses and then querying them with 'info pci', manually assign all PCI addresses before starting the guest. These addresses are not stable across reboots. That will come in a later patch
NB, the PIIX3 (IDE, FDC, ISA-Bridge) will always have slot 1 and VGA will always have slot 2. We declare the Virtio Balloon gets slot 3, and then all remaining slots are for configured devices.
Just wondering, how many slot is there, and shouldn't we try to keep a couple of reserved slots there for future needs, not important now but if we want to make them stable later that may be needed then ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Fri, Jan 15, 2010 at 09:05:44PM +0100, Daniel Veillard wrote:
On Fri, Jan 08, 2010 at 05:23:29PM +0000, Daniel P. Berrange wrote:
Instead of relying on QEMU to assign PCI addresses and then querying them with 'info pci', manually assign all PCI addresses before starting the guest. These addresses are not stable across reboots. That will come in a later patch
NB, the PIIX3 (IDE, FDC, ISA-Bridge) will always have slot 1 and VGA will always have slot 2. We declare the Virtio Balloon gets slot 3, and then all remaining slots are for configured devices.
Just wondering, how many slot is there, and shouldn't we try to keep a couple of reserved slots there for future needs, not important now but if we want to make them stable later that may be needed then
We're quite short on PCI slots currently - QEMU only has a single PCI domain with a single PCI bus. That gives 32 slots max. Since NICs and Virtio Disks each require 1 slot per device I don't want to reserve any more than are absolutely neccessary. We need to encourage QEMU developers to add further PCI buses or domains which would give us 100's of slots Or encourage them to create a VirtIO disk controller, so can we make more efficient usage of slots. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

Replace -balloon virtio With -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 This allows it to get correct assigned PCI address as declared in previous patch * src/qemu/qemu_conf.c: Convert Virtio ballon to -device and give it an explicit PCI address * tests/qemuxml2argvdata/qemuxml2argv-*args: Add in virtio balloon where appropriate --- src/qemu/qemu_conf.c | 8 +++++++- .../qemuxml2argv-channel-guestfwd.args | 2 +- .../qemuxml2argv-console-compat-chardev.args | 2 +- .../qemuxml2argv-disk-usb-device.args | 2 +- .../qemuxml2argv-hostdev-pci-address-device.args | 2 +- .../qemuxml2argv-hostdev-usb-address-device.args | 2 +- .../qemuxml2argv-net-virtio-device.args | 2 +- .../qemuxml2argv-parallel-tcp-chardev.args | 2 +- .../qemuxml2argv-serial-dev-chardev.args | 2 +- .../qemuxml2argv-serial-file-chardev.args | 2 +- .../qemuxml2argv-serial-many-chardev.args | 2 +- .../qemuxml2argv-serial-pty-chardev.args | 2 +- .../qemuxml2argv-serial-tcp-chardev.args | 2 +- .../qemuxml2argv-serial-tcp-telnet-chardev.args | 2 +- .../qemuxml2argv-serial-udp-chardev.args | 2 +- .../qemuxml2argv-serial-unix-chardev.args | 2 +- .../qemuxml2argv-serial-vc-chardev.args | 2 +- .../qemuxml2argv-sound-device.args | 2 +- .../qemuxml2argv-watchdog-device.args | 2 +- 19 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 415e6da..40c9e4b 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -3748,8 +3748,14 @@ int qemudBuildCommandLine(virConnectPtr conn, /* QEMU changed its default behavior to not include the virtio balloon * device. Explicitly request it to ensure it will be present. + * + * NB: Earlier we declared that VirtIO balloon will always be in + * slot 0x3 on bus 0x0 */ - if (qemuCmdFlags & QEMUD_CMD_FLAG_BALLOON) { + if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) { + ADD_ARG_LIT("-device"); + ADD_ARG_LIT("virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3"); + } else if (qemuCmdFlags & QEMUD_CMD_FLAG_BALLOON) { ADD_ARG_LIT("-balloon"); ADD_ARG_LIT("virtio"); } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args b/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args index e93e934..4102dd5 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-guestfwd.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev pipe,id=channel0,path=/tmp/guestfwd -netdev user,guestfwd=tcp:10.0.2.1:4600,chardev=channel0,id=user-channel0 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev pipe,id=channel0,path=/tmp/guestfwd -netdev user,guestfwd=tcp:10.0.2.1:4600,chardev=channel0,id=user-channel0 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.args index 81ca364..a0c48ea 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-console-compat-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev pty,id=serial0 -device isa-serial,chardev=serial0 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev pty,id=serial0 -device isa-serial,chardev=serial0 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device.args index d12d61c..9a41f66 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-usb-device.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=none,id=drive-ide0-0-0 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 -drive file=/tmp/usbdisk.img,if=none,id=drive-usb-disk0 -device usb-storage,drive=drive-usb-disk0,id=usb-disk0 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=none,id=drive-ide0-0-0 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 -drive file=/tmp/usbdisk.img,if=none,id=drive-usb-disk0 -device usb-storage,drive=drive-usb-disk0,id=usb-disk0 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args index 611950a..1b8a130 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address-device.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest2 -usb -device pci-assign,host=06:12.5,id=hostpci0,addr=4 +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest2 -usb -device pci-assign,host=06:12.5,id=hostpci0,bus=pci.0,addr=0x4 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.args b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.args index 70f48c4..cdab007 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address-device.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -device usb-host,hostbus=014,hostaddr=006,id=hostusb0 +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -device usb-host,hostbus=014,hostaddr=006,id=hostusb0 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args index 9324047..698ad3a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -netdev user,id=netdev0 -device virtio-net-pci,netdev=netdev0,id=virtio-nic0,mac=00:11:22:33:44:55,addr=4 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -netdev user,id=netdev0 -device virtio-net-pci,netdev=netdev0,id=virtio-nic0,mac=00:11:22:33:44:55,bus=pci.0,addr=0x4 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.args index 1961948..5a5f86a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev socket,id=parallel0,host=127.0.0.1,port=9999,server,nowait -device isa-parallel,chardev=parallel0 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev socket,id=parallel0,host=127.0.0.1,port=9999,server,nowait -device isa-parallel,chardev=parallel0 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.args index d166f48..4fea22e 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev tty,id=serial0,path=/dev/ttyS2 -device isa-serial,chardev=serial0 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev tty,id=serial0,path=/dev/ttyS2 -device isa-serial,chardev=serial0 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.args index b039bdf..b2032e7 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-file-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev file,id=serial0,path=/tmp/serial.log -device isa-serial,chardev=serial0 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev file,id=serial0,path=/tmp/serial.log -device isa-serial,chardev=serial0 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.args index 419ea00..3b1b5ec 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-many-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev pty,id=serial0 -device isa-serial,chardev=serial0 -chardev file,id=serial1,path=/tmp/serial.log -device isa-serial,chardev=serial1 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev pty,id=serial0 -device isa-serial,chardev=serial0 -chardev file,id=serial1,path=/tmp/serial.log -device isa-serial,chardev=serial1 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.args index 81ca364..a0c48ea 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev pty,id=serial0 -device isa-serial,chardev=serial0 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev pty,id=serial0 -device isa-serial,chardev=serial0 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.args index 526af51..787293c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev socket,id=serial0,host=127.0.0.1,port=9999 -device isa-serial,chardev=serial0 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev socket,id=serial0,host=127.0.0.1,port=9999 -device isa-serial,chardev=serial0 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.args index 842261b..5d25274 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev socket,id=serial0,host=127.0.0.1,port=9999,telnet,server,nowait -device isa-serial,chardev=serial0 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev socket,id=serial0,host=127.0.0.1,port=9999,telnet,server,nowait -device isa-serial,chardev=serial0 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.args index 7d7d2a8..07d0980 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev udp,id=serial0,host=127.0.0.1,port=9998,localaddr=127.0.0.1,localport=9999 -device isa-serial,chardev=serial0 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev udp,id=serial0,host=127.0.0.1,port=9998,localaddr=127.0.0.1,localport=9999 -device isa-serial,chardev=serial0 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.args index b326238..384303a 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev socket,id=serial0,path=/tmp/serial.sock -device isa-serial,chardev=serial0 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev socket,id=serial0,path=/tmp/serial.sock -device isa-serial,chardev=serial0 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.args index 4c7e654..eb7600c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc-chardev.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev vc,id=serial0 -device isa-serial,chardev=serial0 -usb +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -chardev socket,id=monitor,path=/tmp/test-monitor,server,nowait -mon chardev=monitor,mode=readline -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -chardev vc,id=serial0 -device isa-serial,chardev=serial0 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args b/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args index b9adec6..8a777ce 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -soundhw pcspk -device ES1370,id=sound1,addr=4 -device sb16,id=sound2 -device AC97,id=sound3,addr=5 +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -soundhw pcspk -device ES1370,id=sound1,bus=pci.0,addr=0x4 -device sb16,id=sound2 -device AC97,id=sound3,bus=pci.0,addr=0x5 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.args b/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.args index f05111c..72d1bbe 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-watchdog-device.args @@ -1 +1 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -device ib700,id=watchdog0,addr=4 -watchdog-action poweroff +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -device ib700,id=watchdog0,bus=pci.0,addr=0x4 -watchdog-action poweroff -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 -- 1.6.5.2

On Fri, Jan 08, 2010 at 05:23:30PM +0000, Daniel P. Berrange wrote:
Replace
-balloon virtio
With
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
This allows it to get correct assigned PCI address as declared in previous patch
ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Fri, Jan 08, 2010 at 05:22:56PM +0000, Daniel P. Berrange wrote:
This series is a merge of two previous series I posted
http://www.redhat.com/archives/libvir-list/2009-December/msg00232.html http://www.redhat.com/archives/libvir-list/2009-December/msg00392.html
It accomplishes quite a lot of things, having major impact on the QEMU driver, hopefully all in a postive way :-)
In particular it does
* Add standard XML syntax for addressing of PCI devices, and disk drives * Add support for disk controllers as a managed device in XML * Add support for disk controller hotplug/unplug * Convert everything over to use QEMU's -device flag where available * Add PCI addressing when using -device * Introduce a way to give every device a unique 'alias' name in the XML format
I can't promise it works perfectly, but i've done quite alot of positive testing with it now & believe all the back comptability stuff is working right.
Since this is a long series, it might be helpful to see the results in the XML and command line Starting with this initial XML config which the application defines <domain type='kvm' id='2'> <name>everything</name> <uuid>c7a1edbd-edaf-9455-926a-d65c36db1809</uuid> <memory>219200</memory> <currentMemory>219136</currentMemory> <vcpu>1</vcpu> <os> <type arch='i686' machine='pc-0.11'>hvm</type> <kernel>/home/berrange/vmlinuz-PAE</kernel> <initrd>/home/berrange/initrd-PAE.img</initrd> <boot dev='hd'/> </os> <features> <acpi/> </features> <clock offset='utc'/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>destroy</on_crash> <devices> <emulator>/home/berrange/usr/qemu-0.12/bin/qemu</emulator> <disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> <source file='/home/berrange/VirtualMachines/plain.qcow'/> <target dev='vda' bus='virtio'/> </disk> <disk type='file' device='cdrom'> <source file='/home/berrange/gpxe.iso'/> <target dev='hdc' bus='ide'/> <readonly/> </disk> <disk type='file' device='disk'> <source file='/home/berrange/output.img'/> <target dev='sdb' bus='usb'/> </disk> <disk type='file' device='disk'> <source file='/home/berrange/output.img'/> <target dev='sda' bus='scsi'/> </disk> <disk type='file' device='disk'> <source file='/home/berrange/output.img'/> <target dev='sdz' bus='scsi'/> </disk> <disk type='file' device='disk'> <source file='/home/berrange/output.img'/> <target dev='sdaf' bus='scsi'/> </disk> <interface type='user'> <mac address='52:54:00:5b:ef:21'/> <model type='ne2k_pci'/> </interface> <interface type='mcast'> <mac address='52:54:00:1c:dc:98'/> <source address='230.0.0.1' port='5558'/> <model type='virtio'/> </interface> <interface type='network'> <mac address='52:54:00:f7:c5:0e'/> <source network='default'/> <target dev='vnet0'/> <model type='e1000'/> </interface> <interface type='user'> <mac address='52:54:00:56:6c:55'/> <model type='pcnet'/> </interface> <interface type='user'> <mac address='52:54:00:ca:0d:58'/> <model type='rtl8139'/> </interface> <serial type='pty'> <source path='/dev/pts/10'/> <target port='0'/> </serial> <parallel type='pty'> <source path='/dev/pts/17'/> <target port='0'/> </parallel> <console type='pty' tty='/dev/pts/10'> <source path='/dev/pts/10'/> <target port='0'/> </console> <input type='tablet' bus='usb'/> <input type='mouse' bus='ps2'/> <graphics type='vnc' port='5900' autoport='yes'/> <sound model='ac97'/> <sound model='es1370'/> <video> <model type='cirrus' vram='9216' heads='1'/> </video> <hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x15' slot='0x00' function='0x0'/> </source> </hostdev> <hostdev mode='subsystem' type='usb' managed='yes'> <source> <address bus='4' device='2'/> </source> </hostdev> <watchdog model='i6300esb' action='reset'/> </devices> </domain> With the latest QEMU we now generate command line that looks like this LC_ALL=C PATH=/usr/lib/qt-3.3/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin HOME=/root USER=root LOGNAME=root QEMU_AUDIO_DRV=none /home/berrange/usr/qemu-0.12/bin/qemu -S -M pc-0.11 -enable-kvm -m 214 -smp 1 -name everything -uuid c7a1edbd-edaf-9455-926a-d65c36db1809 -nodefaults -chardev socket,id=monitor,path=/var/lib/libvirt/qemu/everything.monitor,server,nowait -mon chardev=monitor,mode=readline -boot c -kernel /home/berrange/vmlinuz-PAE -initrd /home/berrange/initrd-PAE.img -device lsi,id=scsi0,addr=13 -device lsi,id=scsi1,addr=14 -device lsi,id=scsi2,addr=15 -device lsi,id=scsi3,addr=16 -device lsi,id=scsi4,addr=17 -drive file=/home/berrange/VirtualMachines/plain.qcow,if=none,id=drive-virtio-disk0,format=qcow2 -device virtio-blk-pci,addr=4,drive=drive-virtio-disk0,id=virtio-disk0 -drive file=/home/berrange/gpxe.iso,if=none,media=cdrom,id=drive-ide0-1-0 -device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 -drive file=/home/berrange/output.img,if=none,id=drive-usb-disk1 -device usb-storage,drive=drive-usb-disk1,id=usb-disk1 -drive file=/home/berrange/output.img,if=none,id=drive-scsi0-0-0 -device scsi-disk,bus=scsi0.0,scsi-id=0,drive=drive-scsi0-0-0,id=scsi0-0-0 -drive file=/home/berrange/output.img,if=none,id=drive-scsi3-0-4 -device scsi-disk,bus=scsi3.0,scsi-id=4,drive=drive-scsi3-0-4,id=scsi3-0-4 -drive file=/home/berrange/output.img,if=none,id=drive-scsi4-0-3 -device scsi-disk,bus=scsi4.0,scsi-id=3,drive=drive-scsi4-0-3,id=scsi4-0-3 -netdev user,id=netdev0 -device ne2k_pci,netdev=netdev0,id=ne2k_pci-nic0,mac=52:54:00:5b:ef:21,addr=5 -netdev socket,mcast=230.0.0.1:5558,id=netdev1 -device virtio-net-pci,netdev=netdev1,id=virtio-nic1,mac=52:54:00:1c:dc:98,addr=6 -netdev tap,fd=21,id=netdev2 -device e1000,netdev=netdev2,id=e1000-nic2,mac=52:54:00:f7:c5:0e,addr=7 -netdev user,id=netdev3 -device pcnet,netdev=netdev3,id=pcnet-nic3,mac=52:54:00:56:6c:55,addr=8 -netdev user,id=netdev4 -device rtl8139,netdev=netdev4,id=rtl8139-nic4,mac=52:54:00:ca:0d:58,addr=9 -chardev pty,id=serial0 -device isa-serial,chardev=serial0 -chardev pty,id=parallel0 -device isa-parallel,chardev=parallel0 -usb -device usb-tablet,id=input0 -vnc 127.0.0.1:0 -vga cirrus -device AC97,id=sound0,addr=10 -device ES1370,id=sound1,addr=11 -device i6300esb,id=watchdog0,addr=18 -watchdog-action reset -device pci-assign,host=15:00.0,id=hostpci0,addr=12 -device usb-host,hostbus=004,hostaddr=002,id=hostusb1 If you query the XML dump while the VM is running, you'll see the extra address information, alias names, and disk controller elements present. eg like this <domain type='kvm' id='2'> <name>everything</name> <uuid>c7a1edbd-edaf-9455-926a-d65c36db1809</uuid> <memory>219200</memory> <currentMemory>219136</currentMemory> <vcpu>1</vcpu> <os> <type arch='i686' machine='pc-0.11'>hvm</type> <kernel>/home/berrange/vmlinuz-PAE</kernel> <initrd>/home/berrange/initrd-PAE.img</initrd> <boot dev='hd'/> </os> <features> <acpi/> </features> <clock offset='utc'/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>destroy</on_crash> <devices> <emulator>/home/berrange/usr/qemu-0.12/bin/qemu</emulator> <disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> <source file='/home/berrange/VirtualMachines/plain.qcow'/> <target dev='vda' bus='virtio'/> <alias name='virtio-disk0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> </disk> <disk type='file' device='cdrom'> <source file='/home/berrange/gpxe.iso'/> <target dev='hdc' bus='ide'/> <readonly/> <alias name='ide0-1-0'/> <address type='drive' controller='0' bus='1' unit='0'/> </disk> <disk type='file' device='disk'> <source file='/home/berrange/output.img'/> <target dev='sdb' bus='usb'/> <alias name='usb-disk1'/> </disk> <disk type='file' device='disk'> <source file='/home/berrange/output.img'/> <target dev='sda' bus='scsi'/> <alias name='scsi0-0-0'/> <address type='drive' controller='0' bus='0' unit='0'/> </disk> <disk type='file' device='disk'> <source file='/home/berrange/output.img'/> <target dev='sdz' bus='scsi'/> <alias name='scsi3-0-4'/> <address type='drive' controller='3' bus='0' unit='4'/> </disk> <disk type='file' device='disk'> <source file='/home/berrange/output.img'/> <target dev='sdaf' bus='scsi'/> <alias name='scsi4-0-3'/> <address type='drive' controller='4' bus='0' unit='3'/> </disk> <controller type='ide' index='0'> <alias name='ide0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> </controller> <controller type='scsi' index='0'> <alias name='scsi1'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x0c' function='0x0'/> </controller> <controller type='scsi' index='1'> <alias name='scsi2'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x0d' function='0x0'/> </controller> <controller type='scsi' index='2'> <alias name='scsi3'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x0e' function='0x0'/> </controller> <controller type='scsi' index='3'> <alias name='scsi4'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x0f' function='0x0'/> </controller> <controller type='scsi' index='4'> <alias name='scsi5'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x10' function='0x0'/> </controller> <interface type='user'> <mac address='52:54:00:5b:ef:21'/> <model type='ne2k_pci'/> <alias name='ne2k_pci-nic0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </interface> <interface type='mcast'> <mac address='52:54:00:1c:dc:98'/> <source address='230.0.0.1' port='5558'/> <model type='virtio'/> <alias name='virtio-nic1'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> </interface> <interface type='network'> <mac address='52:54:00:f7:c5:0e'/> <source network='default'/> <target dev='vnet0'/> <model type='e1000'/> <alias name='e1000-nic2'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> </interface> <interface type='user'> <mac address='52:54:00:56:6c:55'/> <model type='pcnet'/> <alias name='pcnet-nic3'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/> </interface> <interface type='user'> <mac address='52:54:00:ca:0d:58'/> <model type='rtl8139'/> <alias name='rtl8139-nic4'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/> </interface> <serial type='pty'> <source path='/dev/pts/10'/> <target port='0'/> <alias name='serial0'/> </serial> <parallel type='pty'> <source path='/dev/pts/17'/> <target port='0'/> <alias name='parallel0'/> </parallel> <console type='pty' tty='/dev/pts/10'> <source path='/dev/pts/10'/> <target port='0'/> <alias name='serial0'/> </console> <input type='tablet' bus='usb'/> <input type='mouse' bus='ps2'/> <graphics type='vnc' port='5900' autoport='yes'/> <sound model='ac97'> <alias name='sound0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/> </sound> <sound model='es1370'> <alias name='sound1'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/> </sound> <video> <model type='cirrus' vram='9216' heads='1'/> <alias name='video0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> </video> <hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x15' slot='0x00' function='0x0'/> </source> <address type='pci' domain='0x0000' bus='0x00' slot='0x12' function='0x0'/> <alias name='hostpci0'/> </hostdev> <hostdev mode='subsystem' type='usb' managed='yes'> <source> <address bus='4' device='2'/> </source> <alias name='hostusb1'/> </hostdev> <watchdog model='i6300esb' action='reset'> <alias name='watchdog0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x11' function='0x0'/> </watchdog> </devices> <seclabel type='dynamic' model='selinux'> <label>system_u:system_r:svirt_t:s0:c133,c417</label> <imagelabel>system_u:object_r:svirt_image_t:s0:c133,c417</imagelabel> </seclabel> </domain> Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

Hi, On Fri, Jan 8, 2010 at 6:22 PM, Daniel P. Berrange <berrange@redhat.com> wrote:
This series is a merge of two previous series I posted
http://www.redhat.com/archives/libvir-list/2009-December/msg00232.html http://www.redhat.com/archives/libvir-list/2009-December/msg00392.html
It accomplishes quite a lot of things, having major impact on the QEMU driver, hopefully all in a postive way :-)
do you happen to have a git repository from which the patches can be pulled? This would ease testing quite a bit since it's become a rather voluminous series ;-) Thanks, Wolfgang
In particular it does
* Add standard XML syntax for addressing of PCI devices, and disk drives * Add support for disk controllers as a managed device in XML * Add support for disk controller hotplug/unplug * Convert everything over to use QEMU's -device flag where available * Add PCI addressing when using -device * Introduce a way to give every device a unique 'alias' name in the XML format
I can't promise it works perfectly, but i've done quite alot of positive testing with it now & believe all the back comptability stuff is working right.
-- Libvir-list mailing list Libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

On Wed, Jan 13, 2010 at 02:16:45PM +0100, Wolfgang Mauerer wrote:
Hi,
On Fri, Jan 8, 2010 at 6:22 PM, Daniel P. Berrange <berrange@redhat.com> wrote:
This series is a merge of two previous series I posted
http://www.redhat.com/archives/libvir-list/2009-December/msg00232.html http://www.redhat.com/archives/libvir-list/2009-December/msg00392.html
It accomplishes quite a lot of things, having major impact on the QEMU driver, hopefully all in a postive way :-)
do you happen to have a git repository from which the patches can be pulled? This would ease testing quite a bit since it's become a rather voluminous series ;-)
Yep, its on the 'device-info' branch on gitorious http://gitorious.org/~berrange/libvirt/staging/commits/device-info Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
participants (4)
-
Daniel P. Berrange
-
Daniel Veillard
-
Paolo Bonzini
-
Wolfgang Mauerer