diff --git a/.travis.yml b/.travis.yml index 89c30aefa7..ad66e5bca3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ notifications: on_failure: always env: global: - - TEST_CMD="make check" + - TEST_CMD="" - EXTRA_CONFIG="" # Development packages, EXTRA_PKGS saved for additional builds - CORE_PKGS="libusb-1.0-0-dev libiscsi-dev librados-dev libncurses5-dev" @@ -20,31 +20,51 @@ env: - GUI_PKGS="libgtk-3-dev libvte-2.90-dev libsdl1.2-dev libpng12-dev libpixman-1-dev" - EXTRA_PKGS="" matrix: + # Group major targets together with their linux-user counterparts - TARGETS=alpha-softmmu,alpha-linux-user - - TARGETS=arm-softmmu,arm-linux-user - - TARGETS=aarch64-softmmu,aarch64-linux-user - - TARGETS=cris-softmmu - - TARGETS=i386-softmmu,x86_64-softmmu - - TARGETS=lm32-softmmu - - TARGETS=m68k-softmmu - - TARGETS=microblaze-softmmu,microblazeel-softmmu + - TARGETS=arm-softmmu,arm-linux-user,armeb-linux-user,aarch64-softmmu,aarch64-linux-user + - TARGETS=cris-softmmu,cris-linux-user + - TARGETS=i386-softmmu,i386-linux-user,x86_64-softmmu,x86_64-linux-user + - TARGETS=m68k-softmmu,m68k-linux-user + - TARGETS=microblaze-softmmu,microblazeel-softmmu,microblaze-linux-user,microblazeel-linux-user - TARGETS=mips-softmmu,mips64-softmmu,mips64el-softmmu,mipsel-softmmu - - TARGETS=moxie-softmmu - - TARGETS=or32-softmmu, - - TARGETS=ppc-softmmu,ppc64-softmmu,ppcemb-softmmu - - TARGETS=s390x-softmmu - - TARGETS=sh4-softmmu,sh4eb-softmmu - - TARGETS=sparc-softmmu,sparc64-softmmu - - TARGETS=unicore32-softmmu - - TARGETS=xtensa-softmmu,xtensaeb-softmmu + - TARGETS=mips-linux-user,mips64-linux-user,mips64el-linux-user,mipsel-linux-user,mipsn32-linux-user,mipsn32el-linux-user + - TARGETS=or32-softmmu,or32-linux-user + - TARGETS=ppc-softmmu,ppc64-softmmu,ppcemb-softmmu,ppc-linux-user,ppc64-linux-user,ppc64abi32-linux-user,ppc64le-linux-user + - TARGETS=s390x-softmmu,s390x-linux-user + - TARGETS=sh4-softmmu,sh4eb-softmmu,sh4-linux-user sh4eb-linux-user + - TARGETS=sparc-softmmu,sparc64-softmmu,sparc-linux-user,sparc32plus-linux-user,sparc64-linux-user + - TARGETS=unicore32-softmmu,unicore32-linux-user + # Group remaining softmmu only targets into one build + - TARGETS=lm32-softmmu,moxie-softmmu,tricore-softmmu,xtensa-softmmu,xtensaeb-softmmu +git: + # we want to do this ourselves + submodules: false before_install: + - wget -O - http://people.linaro.org/~alex.bennee/qemu-submodule-git-seed.tar.xz | tar -xvJ - git submodule update --init --recursive - sudo apt-get update -qq - sudo apt-get install -qq ${CORE_PKGS} ${NET_PKGS} ${GUI_PKGS} ${EXTRA_PKGS} -script: "./configure --target-list=${TARGETS} ${EXTRA_CONFIG} && make && ${TEST_CMD}" +before_script: + - ./configure --target-list=${TARGETS} --enable-debug-tcg ${EXTRA_CONFIG} +script: + - make -j2 && ${TEST_CMD} matrix: # We manually include a number of additional build for non-standard bits include: + # Make check target (we only do this once) + - env: + - TARGETS=alpha-softmmu,arm-softmmu,aarch64-softmmu,cris-softmmu, + i386-softmmu,x86_64-softmmu,m68k-softmmu,microblaze-softmmu, + microblazeel-softmmu,mips-softmmu,mips64-softmmu, + mips64el-softmmu,mipsel-softmmu,or32-softmmu,ppc-softmmu, + ppc64-softmmu,ppcemb-softmmu,s390x-softmmu,sh4-softmmu, + sh4eb-softmmu,sparc-softmmu,sparc64-softmmu, + unicore32-softmmu,unicore32-linux-user, + lm32-softmmu,moxie-softmmu,tricore-softmmu,xtensa-softmmu, + xtensaeb-softmmu + TEST_CMD="make check" + compiler: gcc # Debug related options - env: TARGETS=i386-softmmu,x86_64-softmmu EXTRA_CONFIG="--enable-debug" @@ -73,7 +93,6 @@ matrix: compiler: gcc - env: TARGETS=i386-softmmu,x86_64-softmmu EXTRA_CONFIG="--enable-trace-backends=ftrace" - TEST_CMD="" compiler: gcc - env: TARGETS=i386-softmmu,x86_64-softmmu EXTRA_PKGS="liblttng-ust-dev liburcu-dev" diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt index a6197a9133..8313ba6af8 100644 --- a/docs/qapi-code-gen.txt +++ b/docs/qapi-code-gen.txt @@ -1,10 +1,5 @@ = How to use the QAPI code generator = -* Note: as of this writing, QMP does not use QAPI. Eventually QMP -commands will be converted to use QAPI internally. The following -information describes QMP/QAPI as it will exist after the -conversion. - QAPI is a native C API within QEMU which provides management-level functionality to internal/external users. For external users/processes, this interface is made available by a JSON-based @@ -19,7 +14,7 @@ marshaling/dispatch code for the guest agent server running in the guest. This document will describe how the schemas, scripts, and resulting -code is used. +code are used. == QMP/Guest agent schema == @@ -234,6 +229,7 @@ Resulting in this JSON object: "data": { "b": "test string" }, "timestamp": { "seconds": 1267020223, "microseconds": 435656 } } + == Code generation == Schemas are fed into 3 scripts to generate all the code/files that, paired @@ -256,6 +252,8 @@ command which takes that type as a parameter and returns the same type: 'data': {'arg1': 'UserDefOne'}, 'returns': 'UserDefOne' } + { 'event': 'MY_EVENT' } + === scripts/qapi-types.py === Used to generate the C types defined by a schema. The following files are @@ -277,7 +275,7 @@ Example: $ cat qapi-generated/example-qapi-types.c [Uninteresting stuff omitted...] - void qapi_free_UserDefOneList(UserDefOneList * obj) + void qapi_free_UserDefOneList(UserDefOneList *obj) { QapiDeallocVisitor *md; Visitor *v; @@ -292,7 +290,7 @@ Example: qapi_dealloc_visitor_cleanup(md); } - void qapi_free_UserDefOne(UserDefOne * obj) + void qapi_free_UserDefOne(UserDefOne *obj) { QapiDeallocVisitor *md; Visitor *v; @@ -331,11 +329,11 @@ Example: struct UserDefOne { int64_t integer; - char * string; + char *string; }; - void qapi_free_UserDefOneList(UserDefOneList * obj); - void qapi_free_UserDefOne(UserDefOne * obj); + void qapi_free_UserDefOneList(UserDefOneList *obj); + void qapi_free_UserDefOne(UserDefOne *obj); #endif @@ -364,7 +362,7 @@ Example: $ cat qapi-generated/example-qapi-visit.c [Uninteresting stuff omitted...] - static void visit_type_UserDefOne_fields(Visitor *m, UserDefOne ** obj, Error **errp) + static void visit_type_UserDefOne_fields(Visitor *m, UserDefOne **obj, Error **errp) { Error *err = NULL; visit_type_int(m, &(*obj)->integer, "integer", &err); @@ -380,7 +378,7 @@ Example: error_propagate(errp, err); } - void visit_type_UserDefOne(Visitor *m, UserDefOne ** obj, const char *name, Error **errp) + void visit_type_UserDefOne(Visitor *m, UserDefOne **obj, const char *name, Error **errp) { Error *err = NULL; @@ -394,7 +392,7 @@ Example: error_propagate(errp, err); } - void visit_type_UserDefOneList(Visitor *m, UserDefOneList ** obj, const char *name, Error **errp) + void visit_type_UserDefOneList(Visitor *m, UserDefOneList **obj, const char *name, Error **errp) { Error *err = NULL; GenericList *i, **prev; @@ -427,8 +425,8 @@ Example: [Visitors for builtin types omitted...] - void visit_type_UserDefOne(Visitor *m, UserDefOne ** obj, const char *name, Error **errp); - void visit_type_UserDefOneList(Visitor *m, UserDefOneList ** obj, const char *name, Error **errp); + void visit_type_UserDefOne(Visitor *m, UserDefOne **obj, const char *name, Error **errp); + void visit_type_UserDefOneList(Visitor *m, UserDefOneList **obj, const char *name, Error **errp); #endif @@ -451,10 +449,12 @@ $(prefix)qmp-commands.h: Function prototypes for the QMP commands Example: + $ python scripts/qapi-commands.py --output-dir="qapi-generated" + --prefix="example-" --input-file=example-schema.json $ cat qapi-generated/example-qmp-marshal.c [Uninteresting stuff omitted...] - static void qmp_marshal_output_my_command(UserDefOne * ret_in, QObject **ret_out, Error **errp) + static void qmp_marshal_output_my_command(UserDefOne *ret_in, QObject **ret_out, Error **errp) { Error *local_err = NULL; QmpOutputVisitor *mo = qmp_output_visitor_new(); @@ -480,11 +480,11 @@ Example: static void qmp_marshal_input_my_command(QDict *args, QObject **ret, Error **errp) { Error *local_err = NULL; - UserDefOne * retval = NULL; + UserDefOne *retval = NULL; QmpInputVisitor *mi = qmp_input_visitor_new_strict(QOBJECT(args)); QapiDeallocVisitor *md; Visitor *v; - UserDefOne * arg1 = NULL; + UserDefOne *arg1 = NULL; v = qmp_input_get_visitor(mi); visit_type_UserDefOne(v, &arg1, "arg1", &local_err); @@ -525,6 +525,66 @@ Example: #include "qapi/qmp/qdict.h" #include "qapi/error.h" - UserDefOne * qmp_my_command(UserDefOne * arg1, Error **errp); + UserDefOne *qmp_my_command(UserDefOne *arg1, Error **errp); + + #endif + +=== scripts/qapi-event.py === + +Used to generate the event-related C code defined by a schema. The +following files are created: + +$(prefix)qapi-event.h - Function prototypes for each event type, plus an + enumeration of all event names +$(prefix)qapi-event.c - Implementation of functions to send an event + +Example: + + $ python scripts/qapi-event.py --output-dir="qapi-generated" + --prefix="example-" --input-file=example-schema.json + $ cat qapi-generated/example-qapi-event.c +[Uninteresting stuff omitted...] + + void qapi_event_send_my_event(Error **errp) + { + QDict *qmp; + Error *local_err = NULL; + QMPEventFuncEmit emit; + emit = qmp_event_get_func_emit(); + if (!emit) { + return; + } + + qmp = qmp_event_build_dict("MY_EVENT"); + + emit(EXAMPLE_QAPI_EVENT_MY_EVENT, qmp, &local_err); + + error_propagate(errp, local_err); + QDECREF(qmp); + } + + const char *EXAMPLE_QAPIEvent_lookup[] = { + "MY_EVENT", + NULL, + }; + $ cat qapi-generated/example-qapi-event.h +[Uninteresting stuff omitted...] + + #ifndef EXAMPLE_QAPI_EVENT_H + #define EXAMPLE_QAPI_EVENT_H + + #include "qapi/error.h" + #include "qapi/qmp/qdict.h" + #include "example-qapi-types.h" + + + void qapi_event_send_my_event(Error **errp); + + extern const char *EXAMPLE_QAPIEvent_lookup[]; + typedef enum EXAMPLE_QAPIEvent + { + EXAMPLE_QAPI_EVENT_MY_EVENT = 0, + EXAMPLE_QAPI_EVENT_MAX = 1, + } EXAMPLE_QAPIEvent; #endif diff --git a/os-posix.c b/os-posix.c index cb2a7f7ad7..4898ebf4a2 100644 --- a/os-posix.c +++ b/os-posix.c @@ -204,45 +204,49 @@ static void change_root(void) void os_daemonize(void) { if (daemonize) { - pid_t pid; + pid_t pid; - if (pipe(fds) == -1) - exit(1); - - pid = fork(); - if (pid > 0) { - uint8_t status; - ssize_t len; - - close(fds[1]); - - again: - len = read(fds[0], &status, 1); - if (len == -1 && (errno == EINTR)) - goto again; - - if (len != 1) - exit(1); - else if (status == 1) { - fprintf(stderr, "Could not acquire pidfile: %s\n", strerror(errno)); - exit(1); - } else - exit(0); - } else if (pid < 0) + if (pipe(fds) == -1) { exit(1); + } - close(fds[0]); - qemu_set_cloexec(fds[1]); + pid = fork(); + if (pid > 0) { + uint8_t status; + ssize_t len; - setsid(); + close(fds[1]); - pid = fork(); - if (pid > 0) - exit(0); - else if (pid < 0) - exit(1); + again: + len = read(fds[0], &status, 1); + if (len == -1 && (errno == EINTR)) { + goto again; + } + if (len != 1) { + exit(1); + } + else if (status == 1) { + fprintf(stderr, "Could not acquire pidfile\n"); + exit(1); + } else { + exit(0); + } + } else if (pid < 0) { + exit(1); + } - umask(027); + close(fds[0]); + qemu_set_cloexec(fds[1]); + + setsid(); + + pid = fork(); + if (pid > 0) { + exit(0); + } else if (pid < 0) { + exit(1); + } + umask(027); signal(SIGTSTP, SIG_IGN); signal(SIGTTOU, SIG_IGN); @@ -255,24 +259,25 @@ void os_setup_post(void) int fd = 0; if (daemonize) { - uint8_t status = 0; - ssize_t len; + uint8_t status = 0; + ssize_t len; again1: - len = write(fds[1], &status, 1); - if (len == -1 && (errno == EINTR)) - goto again1; - - if (len != 1) - exit(1); - + len = write(fds[1], &status, 1); + if (len == -1 && (errno == EINTR)) { + goto again1; + } + if (len != 1) { + exit(1); + } if (chdir("/")) { perror("not able to chdir to /"); exit(1); } - TFR(fd = qemu_open("/dev/null", O_RDWR)); - if (fd == -1) - exit(1); + TFR(fd = qemu_open("/dev/null", O_RDWR)); + if (fd == -1) { + exit(1); + } } change_root(); @@ -314,6 +319,8 @@ int qemu_create_pidfile(const char *filename) return -1; } if (lockf(fd, F_TLOCK, 0) == -1) { + fprintf(stderr, "lock file '%s' failed: %s\n", + filename, strerror(errno)); close(fd); return -1; } diff --git a/scripts/kvm/vmxcap b/scripts/kvm/vmxcap index c90eda497a..8f0371f498 100755 --- a/scripts/kvm/vmxcap +++ b/scripts/kvm/vmxcap @@ -99,7 +99,7 @@ controls = [ Misc( name = 'Basic VMX Information', bits = { - (0, 31): 'Revision', + (0, 30): 'Revision', (32,44): 'VMCS size', 48: 'VMCS restricted to 32 bit addresses', 49: 'Dual-monitor support', @@ -169,7 +169,9 @@ controls = [ 12: 'Enable INVPCID', 13: 'Enable VM functions', 14: 'VMCS shadowing', - 18: 'EPT-violation #VE' + 16: 'RDSEED exiting', + 18: 'EPT-violation #VE', + 20: 'Enable XSAVES/XRSTORS', }, cap_msr = MSR_IA32_VMX_PROCBASED_CTLS2, ), @@ -195,7 +197,7 @@ controls = [ name = 'VM-Entry controls', bits = { 2: 'Load debug controls', - 9: 'IA-64 mode guest', + 9: 'IA-32e mode guest', 10: 'Entry to SMM', 11: 'Deactivate dual-monitor treatment', 13: 'Load IA32_PERF_GLOBAL_CTRL', @@ -216,7 +218,7 @@ controls = [ 8: 'Wait-for-SIPI activity state', 15: 'IA32_SMBASE support', (16,24): 'Number of CR3-target values', - (25,27): 'MSR-load/store count recommenation', + (25,27): 'MSR-load/store count recommendation', 28: 'IA32_SMM_MONITOR_CTL[2] can be set to 1', 29: 'VMWRITE to VM-exit information fields', (32,63): 'MSEG revision identifier', diff --git a/tests/.gitignore b/tests/.gitignore index c71c11020e..e2e4957332 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -14,11 +14,14 @@ test-int128 test-iov test-mul64 test-opts-visitor +test-qapi-event.[ch] test-qapi-types.[ch] test-qapi-visit.[ch] test-qdev-global-props +test-qemu-opts test-qmp-commands test-qmp-commands.h +test-qmp-event test-qmp-input-strict test-qmp-input-visitor test-qmp-marshal.c diff --git a/tests/Makefile b/tests/Makefile index f5de29c0b9..834279cd0d 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -193,26 +193,27 @@ check-qtest-xtensaeb-y = $(check-qtest-xtensa-y) # qom-test works for all sysemu architectures: $(foreach target,$(SYSEMU_TARGET_LIST), \ - $(eval check-qtest-$(target)-y += tests/qom-test$(EXESUF))) + $(if $(findstring tests/qom-test$(EXESUF), $(check-qtest-$(target)-y)),, \ + $(eval check-qtest-$(target)-y += tests/qom-test$(EXESUF)))) check-qapi-schema-y := $(addprefix tests/qapi-schema/, \ - comments.json empty.json funny-char.json indented-expr.json \ - missing-colon.json missing-comma-list.json \ - missing-comma-object.json non-objects.json \ - qapi-schema-test.json quoted-structural-chars.json \ - trailing-comma-list.json trailing-comma-object.json \ - unclosed-list.json unclosed-object.json unclosed-string.json \ - duplicate-key.json union-invalid-base.json flat-union-no-base.json \ - flat-union-invalid-discriminator.json \ - flat-union-invalid-branch-key.json flat-union-reverse-define.json \ - flat-union-string-discriminator.json \ - include-simple.json include-relpath.json include-format-err.json \ - include-non-file.json include-no-file.json include-before-err.json \ - include-nested-err.json include-self-cycle.json include-cycle.json \ - include-repetition.json event-nest-struct.json) + comments.json empty.json funny-char.json indented-expr.json \ + missing-colon.json missing-comma-list.json \ + missing-comma-object.json non-objects.json \ + qapi-schema-test.json quoted-structural-chars.json \ + trailing-comma-list.json trailing-comma-object.json \ + unclosed-list.json unclosed-object.json unclosed-string.json \ + duplicate-key.json union-invalid-base.json flat-union-no-base.json \ + flat-union-invalid-discriminator.json \ + flat-union-invalid-branch-key.json flat-union-reverse-define.json \ + flat-union-string-discriminator.json \ + include-simple.json include-relpath.json include-format-err.json \ + include-non-file.json include-no-file.json include-before-err.json \ + include-nested-err.json include-self-cycle.json include-cycle.json \ + include-repetition.json event-nest-struct.json) GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h \ - tests/test-qmp-commands.h tests/test-qapi-event.h + tests/test-qmp-commands.h tests/test-qapi-event.h test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \ tests/check-qlist.o tests/check-qfloat.o tests/check-qjson.o \ @@ -224,7 +225,7 @@ test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \ tests/test-opts-visitor.o tests/test-qmp-event.o test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o \ - tests/test-qapi-event.o + tests/test-qapi-event.o $(test-obj-y): QEMU_INCLUDES += -Itests QEMU_CFLAGS += -I$(SRC_PATH)/tests