Compare commits
497 Commits
pull-input
...
pull-vnc-2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb214ff8ef | ||
|
|
c14e98479b | ||
|
|
64641d8764 | ||
|
|
d279279e2b | ||
|
|
739b7a9075 | ||
|
|
2edaf21b93 | ||
|
|
ab5b3db5d7 | ||
|
|
feca4ac18b | ||
|
|
67891b8a85 | ||
|
|
0598701a49 | ||
|
|
0360fbd076 | ||
|
|
c9299e2fe7 | ||
|
|
a656e22f09 | ||
|
|
3fb5bf5730 | ||
|
|
4dc5615223 | ||
|
|
b0e56e0b63 | ||
|
|
20cfe8810d | ||
|
|
01a9c03c39 | ||
|
|
d3606f0744 | ||
|
|
480eda2eda | ||
|
|
be3bd286bc | ||
|
|
4d13be8b8b | ||
|
|
a42267ef58 | ||
|
|
9e918dc927 | ||
|
|
be3ef5c7fa | ||
|
|
c650c008e3 | ||
|
|
0188fadb7f | ||
|
|
f5f601afce | ||
|
|
9eeb8306d5 | ||
|
|
945473847b | ||
|
|
016d2e1dfa | ||
|
|
41ecc72ba5 | ||
|
|
b0fd8d1868 | ||
|
|
7df2fa3623 | ||
|
|
1d8b512bbc | ||
|
|
af44da87e9 | ||
|
|
f27701510c | ||
|
|
84219c5a21 | ||
|
|
9dbae97723 | ||
|
|
d13fc32ecf | ||
|
|
e223bcad6e | ||
|
|
23825581d7 | ||
|
|
748abce94f | ||
|
|
a70daba377 | ||
|
|
d5ac4f5433 | ||
|
|
c4015bbd50 | ||
|
|
cd9adfdd77 | ||
|
|
7303f83db6 | ||
|
|
4ee4a03b38 | ||
|
|
80b3f79b99 | ||
|
|
cdcdda27fc | ||
|
|
70c5340744 | ||
|
|
45ed0be146 | ||
|
|
7019cb3d88 | ||
|
|
d1a721ab81 | ||
|
|
a242881405 | ||
|
|
5881c296b9 | ||
|
|
7fc2db18ce | ||
|
|
6a1eed3f49 | ||
|
|
5db7d4faa3 | ||
|
|
768167abb9 | ||
|
|
e61716aa9a | ||
|
|
83cc6f8c2f | ||
|
|
90618f4f4d | ||
|
|
7488d481ce | ||
|
|
ba88100219 | ||
|
|
c36c97f880 | ||
|
|
077850b037 | ||
|
|
75b9c321f4 | ||
|
|
fd51ff6328 | ||
|
|
eb16dd9cc9 | ||
|
|
42382f6244 | ||
|
|
bbc01ca7f2 | ||
|
|
cb8b8bf840 | ||
|
|
a9e8f4e7df | ||
|
|
13b6a45565 | ||
|
|
f7d6914654 | ||
|
|
87a91de61a | ||
|
|
b061808d39 | ||
|
|
2872e1929b | ||
|
|
ada82b537e | ||
|
|
deb6ed13eb | ||
|
|
f2e2bc9ca0 | ||
|
|
4b1daa72d3 | ||
|
|
f46e9a0b99 | ||
|
|
5b274ed74d | ||
|
|
9c35126c56 | ||
|
|
e22c357b3e | ||
|
|
d90b94cd78 | ||
|
|
a721d390b3 | ||
|
|
1b8eceee28 | ||
|
|
650f33adbd | ||
|
|
523e7b8ab8 | ||
|
|
e4c35b78bc | ||
|
|
e28c16f61f | ||
|
|
cca7fad576 | ||
|
|
da6ccee418 | ||
|
|
da95324ebe | ||
|
|
a1d59c0ffa | ||
|
|
9397a7c831 | ||
|
|
3e300fa6ad | ||
|
|
6ab39b1bd3 | ||
|
|
00d4f525ec | ||
|
|
6db5bb0f54 | ||
|
|
3794d5482d | ||
|
|
2a48d99335 | ||
|
|
82677ed2f5 | ||
|
|
2a6593cb6a | ||
|
|
1a68b71419 | ||
|
|
6d9412ea81 | ||
|
|
833d46685d | ||
|
|
8dfa3a5e85 | ||
|
|
af354f19a9 | ||
|
|
ffd5e9fe02 | ||
|
|
8ebe65f361 | ||
|
|
1e6ed54ef8 | ||
|
|
382d2db62b | ||
|
|
0c967de9c0 | ||
|
|
acb0ef5801 | ||
|
|
85720d3667 | ||
|
|
10582ff832 | ||
|
|
98a8b52442 | ||
|
|
3812c71ffa | ||
|
|
4e73c78192 | ||
|
|
903585dec6 | ||
|
|
4d09d5291d | ||
|
|
ea71258da4 | ||
|
|
d2ea2bf740 | ||
|
|
deb05c4c4c | ||
|
|
45eb56110b | ||
|
|
f1d9ec8bf7 | ||
|
|
3de3179782 | ||
|
|
c80d1df508 | ||
|
|
3016dca06c | ||
|
|
d575a6ce0e | ||
|
|
08215d8fd8 | ||
|
|
c15424531f | ||
|
|
59dcd29a6c | ||
|
|
04af534d55 | ||
|
|
bfd8f5b754 | ||
|
|
1c1a6d20e0 | ||
|
|
40c84b54dd | ||
|
|
28668b5f31 | ||
|
|
804e654a56 | ||
|
|
297666eba0 | ||
|
|
e8a4846031 | ||
|
|
013c3ac070 | ||
|
|
7796676fdd | ||
|
|
bea0dd7912 | ||
|
|
f121419355 | ||
|
|
ca603eb4d7 | ||
|
|
290d9ee537 | ||
|
|
97c0d93041 | ||
|
|
512918aa79 | ||
|
|
5826ebe27a | ||
|
|
f6022a7684 | ||
|
|
f3d2b0bce0 | ||
|
|
1bf9c0e133 | ||
|
|
e601c1eead | ||
|
|
5833505be6 | ||
|
|
9024ff40ba | ||
|
|
8de6a1cc67 | ||
|
|
2128f8a57e | ||
|
|
a9d7ba03b0 | ||
|
|
27722744e9 | ||
|
|
7b0c0d66e5 | ||
|
|
275e35c6c1 | ||
|
|
f0b01f02a4 | ||
|
|
a4f27cc82c | ||
|
|
0a322e7e7c | ||
|
|
79af357225 | ||
|
|
8e706db21e | ||
|
|
e58f8d1ff9 | ||
|
|
4922fd7d52 | ||
|
|
426d9a1a59 | ||
|
|
9b7a14b064 | ||
|
|
7275585b8c | ||
|
|
0f2d373220 | ||
|
|
f5d7f14646 | ||
|
|
72ac97cdfc | ||
|
|
9d1c128341 | ||
|
|
569be9f055 | ||
|
|
9df5a46632 | ||
|
|
b26696b519 | ||
|
|
fabe9ee113 | ||
|
|
70d246c335 | ||
|
|
fdf8a960e2 | ||
|
|
5b79b1cadd | ||
|
|
8a286ce450 | ||
|
|
c46e983106 | ||
|
|
4e2ca12785 | ||
|
|
d584348589 | ||
|
|
1c38f84373 | ||
|
|
e13951f896 | ||
|
|
0bbac62618 | ||
|
|
98d896d978 | ||
|
|
c282e1fdf7 | ||
|
|
fec9921f0a | ||
|
|
5820f1da51 | ||
|
|
5366092c7a | ||
|
|
004b7f2522 | ||
|
|
766181fe57 | ||
|
|
b222237b7b | ||
|
|
bd0cf596fd | ||
|
|
cd3a4cf631 | ||
|
|
ddef769993 | ||
|
|
6f482f742d | ||
|
|
7ab74849a5 | ||
|
|
1bd0e2d1c4 | ||
|
|
74c3c19765 | ||
|
|
16d12159e2 | ||
|
|
98c10b810a | ||
|
|
a59479e3f3 | ||
|
|
90c772de56 | ||
|
|
25814e8987 | ||
|
|
facdbb0272 | ||
|
|
83d0521a1e | ||
|
|
4782183da3 | ||
|
|
a1097a2614 | ||
|
|
8559e45e51 | ||
|
|
504189a96f | ||
|
|
782730b0bc | ||
|
|
fc345512c5 | ||
|
|
dc8622f2bf | ||
|
|
e36af94f86 | ||
|
|
09722032e1 | ||
|
|
e67905426b | ||
|
|
5e89db7641 | ||
|
|
a2c0fe2fd2 | ||
|
|
ae60e8e378 | ||
|
|
60e19e06a4 | ||
|
|
bcf8315857 | ||
|
|
f7047c2daf | ||
|
|
b25c9dff35 | ||
|
|
db80facefa | ||
|
|
2a93434704 | ||
|
|
f7cd55a023 | ||
|
|
c6f6646c60 | ||
|
|
d49805aeea | ||
|
|
3aff6c2fea | ||
|
|
06a59afac4 | ||
|
|
80008a6a29 | ||
|
|
592fb17691 | ||
|
|
7d5bef0873 | ||
|
|
d61de7255b | ||
|
|
f3cda6e060 | ||
|
|
8bc8912796 | ||
|
|
788fbf042f | ||
|
|
5643fc012c | ||
|
|
e9d21c436f | ||
|
|
fb7da626c0 | ||
|
|
2a2c4830c0 | ||
|
|
05fedeef83 | ||
|
|
706808585a | ||
|
|
c5cb1afc46 | ||
|
|
a491af471b | ||
|
|
075ccb6cd3 | ||
|
|
b21631f3b5 | ||
|
|
ddd6b45ce2 | ||
|
|
e70871d8b5 | ||
|
|
e3bb532cc7 | ||
|
|
84007e8181 | ||
|
|
c68a0409b3 | ||
|
|
d0ece345cb | ||
|
|
8e5977797d | ||
|
|
b87ef3518b | ||
|
|
c998acb03d | ||
|
|
24aeeace7a | ||
|
|
2f859f80c2 | ||
|
|
22227f121b | ||
|
|
92ba1401e0 | ||
|
|
ae3f88f60f | ||
|
|
fa7a1e5219 | ||
|
|
f50def915e | ||
|
|
0a337ed067 | ||
|
|
932f2d7e0f | ||
|
|
c4af6d4b13 | ||
|
|
f35f961ac9 | ||
|
|
1e501653ab | ||
|
|
605474815d | ||
|
|
b85159a3a3 | ||
|
|
80b346040d | ||
|
|
88dae46d18 | ||
|
|
adfc3e91e2 | ||
|
|
7224f66ec3 | ||
|
|
747eb78baa | ||
|
|
adf9d70b0d | ||
|
|
6ad3f09bd4 | ||
|
|
b7b5233ad7 | ||
|
|
591b320ad0 | ||
|
|
6b24119b7f | ||
|
|
b780bf8eff | ||
|
|
1a2858995d | ||
|
|
e2bb4ae746 | ||
|
|
4380be0e99 | ||
|
|
fec0da9cbf | ||
|
|
ec15993d9d | ||
|
|
6b1dd54b6a | ||
|
|
a10678b08e | ||
|
|
6998b6c11b | ||
|
|
d1180c1e57 | ||
|
|
89218c218f | ||
|
|
fc4bde9025 | ||
|
|
029ad4bcf3 | ||
|
|
e3a17ef6cc | ||
|
|
f46b9cc71c | ||
|
|
c1d7572793 | ||
|
|
a1fa7992a9 | ||
|
|
f9b5426fd5 | ||
|
|
7179585688 | ||
|
|
831f4d27b6 | ||
|
|
49bba868df | ||
|
|
2a802aaf63 | ||
|
|
ef18c2f54e | ||
|
|
3048ed6aac | ||
|
|
fa15286a75 | ||
|
|
6ab57a6b80 | ||
|
|
1c33ac5716 | ||
|
|
3334e929ae | ||
|
|
333cb18ff4 | ||
|
|
a1d2db08d8 | ||
|
|
99519e677b | ||
|
|
18e588b197 | ||
|
|
7b0140e49b | ||
|
|
bbd8bb8e32 | ||
|
|
de13d21614 | ||
|
|
66ad0893f0 | ||
|
|
79afc36d91 | ||
|
|
bcb2b582f3 | ||
|
|
6449a41a4d | ||
|
|
a2689242b1 | ||
|
|
4cb88c3c37 | ||
|
|
08da527fd0 | ||
|
|
f068d320de | ||
|
|
471f7e30a4 | ||
|
|
ae9b65e873 | ||
|
|
fd25c0e6dd | ||
|
|
2a0c46da96 | ||
|
|
86946a2d83 | ||
|
|
7721a30442 | ||
|
|
14ac573392 | ||
|
|
3b1a413812 | ||
|
|
d3afacc726 | ||
|
|
f6fe04d566 | ||
|
|
be56f04eea | ||
|
|
5acc765c04 | ||
|
|
aa633469ed | ||
|
|
130f2e7dcb | ||
|
|
da5141fc45 | ||
|
|
25f748e37a | ||
|
|
fb8ad9f2c1 | ||
|
|
46d9dfdad6 | ||
|
|
411bdc7837 | ||
|
|
4e624edaeb | ||
|
|
526d0096e5 | ||
|
|
f1ecb913d8 | ||
|
|
d615efac7c | ||
|
|
8d5c773e32 | ||
|
|
bf01601764 | ||
|
|
61e9924149 | ||
|
|
4a331bb33b | ||
|
|
a35d9be622 | ||
|
|
5b808275f3 | ||
|
|
82432638eb | ||
|
|
80ff35cd3f | ||
|
|
26896cbf35 | ||
|
|
7efea76377 | ||
|
|
b167383ffb | ||
|
|
8597f2e19e | ||
|
|
b44672849a | ||
|
|
40e76f736d | ||
|
|
5dfc05cb1d | ||
|
|
959e41473f | ||
|
|
37654d9e6a | ||
|
|
08397c4b29 | ||
|
|
a373cdb5ce | ||
|
|
aa0f607f61 | ||
|
|
95faaa73df | ||
|
|
e8198f6ea0 | ||
|
|
8c6d96728d | ||
|
|
04bb4d86f1 | ||
|
|
2e95fa1719 | ||
|
|
1ad166b612 | ||
|
|
5db15096d0 | ||
|
|
d34bda716a | ||
|
|
5d039baba4 | ||
|
|
b544c1aba8 | ||
|
|
405a27640b | ||
|
|
50809c8b92 | ||
|
|
4e627aeef8 | ||
|
|
26edf8cc08 | ||
|
|
31e25e3e57 | ||
|
|
ae74bbe7c5 | ||
|
|
f38b161203 | ||
|
|
fd7fbc8ff7 | ||
|
|
ea9a6606b1 | ||
|
|
01b91ac2be | ||
|
|
d4ad9dec14 | ||
|
|
366d4f7e00 | ||
|
|
e09c49f40d | ||
|
|
9d48d3f01c | ||
|
|
9f0355b590 | ||
|
|
d4f005db9b | ||
|
|
711e2f1e9e | ||
|
|
9f9260a3be | ||
|
|
16b96f82cd | ||
|
|
b09481de91 | ||
|
|
de431a655a | ||
|
|
eaad03e472 | ||
|
|
e2a32ebbfe | ||
|
|
e7e898a76a | ||
|
|
e8f6d00c30 | ||
|
|
b728464ae8 | ||
|
|
c1eb2fa3fd | ||
|
|
77549a7809 | ||
|
|
b052e4509b | ||
|
|
870a706735 | ||
|
|
7c82256006 | ||
|
|
487cad8853 | ||
|
|
00cc3e1d70 | ||
|
|
843408b3cf | ||
|
|
f57584dc87 | ||
|
|
8a201bd47e | ||
|
|
81cf8d8adc | ||
|
|
43773ed369 | ||
|
|
c773828aa9 | ||
|
|
f08b617018 | ||
|
|
1d854765df | ||
|
|
58ed270df9 | ||
|
|
0f590e749f | ||
|
|
d94f0a8ecb | ||
|
|
93e22326d6 | ||
|
|
ca0aa40816 | ||
|
|
a6c9eac0d5 | ||
|
|
859d76120b | ||
|
|
0983979b3a | ||
|
|
fddbd80cc9 | ||
|
|
7e4e88656c | ||
|
|
e3eb9806c7 | ||
|
|
3d1b2ff62c | ||
|
|
76782fab1c | ||
|
|
0b91966730 | ||
|
|
d6635c4dbb | ||
|
|
1ac362cdbd | ||
|
|
b15446fdbf | ||
|
|
22524f7262 | ||
|
|
13af91ebf0 | ||
|
|
c9f87b20b9 | ||
|
|
5a05cbeeaa | ||
|
|
6d7e73d62f | ||
|
|
db519cba87 | ||
|
|
76ef2cf549 | ||
|
|
8d242f0ed5 | ||
|
|
0d6ecec252 | ||
|
|
580b6b2aa2 | ||
|
|
c75f3bdf46 | ||
|
|
2af0b20056 | ||
|
|
84390bed59 | ||
|
|
ea80019149 | ||
|
|
85ebd381fd | ||
|
|
99cc598924 | ||
|
|
abd269b7cf | ||
|
|
c2f3426c9b | ||
|
|
e3625d3d6a | ||
|
|
a8c868c386 | ||
|
|
471799d135 | ||
|
|
69447cd8f3 | ||
|
|
80cf625766 | ||
|
|
6ee50af24b | ||
|
|
63f0f45f2e | ||
|
|
9d94020bc6 | ||
|
|
7e1efdf0a3 | ||
|
|
dcd042282d | ||
|
|
9b536adcbe | ||
|
|
ed78cda3de | ||
|
|
2572b37a47 | ||
|
|
924fe1293c | ||
|
|
79b6f2f651 | ||
|
|
374044f08f | ||
|
|
9b1786829a | ||
|
|
f522d2acc5 | ||
|
|
0e1dac6c41 | ||
|
|
eb386aaccc | ||
|
|
501f28ca9d | ||
|
|
38dbd48b24 | ||
|
|
28fb26f19f | ||
|
|
7125c937c9 | ||
|
|
d3b5491897 | ||
|
|
b98dbc9095 | ||
|
|
87446327cc | ||
|
|
b763adf1a6 | ||
|
|
7c8b724826 | ||
|
|
0d73394ad9 | ||
|
|
84351843eb | ||
|
|
fb5be2e833 | ||
|
|
13cc2c3e86 | ||
|
|
a096b3a673 |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -28,3 +28,6 @@
|
|||||||
[submodule "dtc"]
|
[submodule "dtc"]
|
||||||
path = dtc
|
path = dtc
|
||||||
url = git://git.qemu-project.org/dtc.git
|
url = git://git.qemu-project.org/dtc.git
|
||||||
|
[submodule "roms/u-boot"]
|
||||||
|
path = roms/u-boot
|
||||||
|
url = git://git.qemu-project.org/u-boot.git
|
||||||
|
|||||||
@@ -66,16 +66,16 @@ matrix:
|
|||||||
compiler: gcc
|
compiler: gcc
|
||||||
# All the trace backends (apart from dtrace)
|
# All the trace backends (apart from dtrace)
|
||||||
- env: TARGETS=i386-softmmu,x86_64-softmmu
|
- env: TARGETS=i386-softmmu,x86_64-softmmu
|
||||||
EXTRA_CONFIG="--enable-trace-backend=stderr"
|
EXTRA_CONFIG="--enable-trace-backends=stderr"
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
- env: TARGETS=i386-softmmu,x86_64-softmmu
|
- env: TARGETS=i386-softmmu,x86_64-softmmu
|
||||||
EXTRA_CONFIG="--enable-trace-backend=simple"
|
EXTRA_CONFIG="--enable-trace-backends=simple"
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
- env: TARGETS=i386-softmmu,x86_64-softmmu
|
- env: TARGETS=i386-softmmu,x86_64-softmmu
|
||||||
EXTRA_CONFIG="--enable-trace-backend=ftrace"
|
EXTRA_CONFIG="--enable-trace-backends=ftrace"
|
||||||
TEST_CMD=""
|
TEST_CMD=""
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
- env: TARGETS=i386-softmmu,x86_64-softmmu
|
- env: TARGETS=i386-softmmu,x86_64-softmmu
|
||||||
EXTRA_PKGS="liblttng-ust-dev liburcu-dev"
|
EXTRA_PKGS="liblttng-ust-dev liburcu-dev"
|
||||||
EXTRA_CONFIG="--enable-trace-backend=ust"
|
EXTRA_CONFIG="--enable-trace-backends=ust"
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
|
|||||||
10
MAINTAINERS
10
MAINTAINERS
@@ -726,6 +726,16 @@ S: Odd Fixes
|
|||||||
F: gdbstub*
|
F: gdbstub*
|
||||||
F: gdb-xml/
|
F: gdb-xml/
|
||||||
|
|
||||||
|
Memory API
|
||||||
|
M: Paolo Bonzini <pbonzini@redhat.com>
|
||||||
|
S: Supported
|
||||||
|
F: include/exec/ioport.h
|
||||||
|
F: ioport.c
|
||||||
|
F: include/exec/memory.h
|
||||||
|
F: memory.c
|
||||||
|
F: include/exec/memory-internal.h
|
||||||
|
F: exec.c
|
||||||
|
|
||||||
SPICE
|
SPICE
|
||||||
M: Gerd Hoffmann <kraxel@redhat.com>
|
M: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|||||||
4
Makefile
4
Makefile
@@ -52,12 +52,12 @@ GENERATED_HEADERS += trace/generated-events.h
|
|||||||
GENERATED_SOURCES += trace/generated-events.c
|
GENERATED_SOURCES += trace/generated-events.c
|
||||||
|
|
||||||
GENERATED_HEADERS += trace/generated-tracers.h
|
GENERATED_HEADERS += trace/generated-tracers.h
|
||||||
ifeq ($(TRACE_BACKEND),dtrace)
|
ifeq ($(findstring dtrace,$(TRACE_BACKENDS)),dtrace)
|
||||||
GENERATED_HEADERS += trace/generated-tracers-dtrace.h
|
GENERATED_HEADERS += trace/generated-tracers-dtrace.h
|
||||||
endif
|
endif
|
||||||
GENERATED_SOURCES += trace/generated-tracers.c
|
GENERATED_SOURCES += trace/generated-tracers.c
|
||||||
|
|
||||||
ifeq ($(TRACE_BACKEND),ust)
|
ifeq ($(findstring ust,$(TRACE_BACKENDS)),ust)
|
||||||
GENERATED_HEADERS += trace/generated-ust-provider.h
|
GENERATED_HEADERS += trace/generated-ust-provider.h
|
||||||
GENERATED_SOURCES += trace/generated-ust.c
|
GENERATED_SOURCES += trace/generated-ust.c
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ endif
|
|||||||
$(QEMU_PROG).stp-installed: $(SRC_PATH)/trace-events
|
$(QEMU_PROG).stp-installed: $(SRC_PATH)/trace-events
|
||||||
$(call quiet-command,$(TRACETOOL) \
|
$(call quiet-command,$(TRACETOOL) \
|
||||||
--format=stap \
|
--format=stap \
|
||||||
--backend=$(TRACE_BACKEND) \
|
--backends=$(TRACE_BACKENDS) \
|
||||||
--binary=$(bindir)/$(QEMU_PROG) \
|
--binary=$(bindir)/$(QEMU_PROG) \
|
||||||
--target-name=$(TARGET_NAME) \
|
--target-name=$(TARGET_NAME) \
|
||||||
--target-type=$(TARGET_TYPE) \
|
--target-type=$(TARGET_TYPE) \
|
||||||
@@ -58,7 +58,7 @@ $(QEMU_PROG).stp-installed: $(SRC_PATH)/trace-events
|
|||||||
$(QEMU_PROG).stp: $(SRC_PATH)/trace-events
|
$(QEMU_PROG).stp: $(SRC_PATH)/trace-events
|
||||||
$(call quiet-command,$(TRACETOOL) \
|
$(call quiet-command,$(TRACETOOL) \
|
||||||
--format=stap \
|
--format=stap \
|
||||||
--backend=$(TRACE_BACKEND) \
|
--backends=$(TRACE_BACKENDS) \
|
||||||
--binary=$(realpath .)/$(QEMU_PROG) \
|
--binary=$(realpath .)/$(QEMU_PROG) \
|
||||||
--target-name=$(TARGET_NAME) \
|
--target-name=$(TARGET_NAME) \
|
||||||
--target-type=$(TARGET_TYPE) \
|
--target-type=$(TARGET_TYPE) \
|
||||||
@@ -85,6 +85,12 @@ obj-y += disas.o
|
|||||||
obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
|
obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
|
||||||
obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
|
obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/decContext.o
|
||||||
|
obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/decNumber.o
|
||||||
|
obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/dpd/decimal32.o
|
||||||
|
obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/dpd/decimal64.o
|
||||||
|
obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/dpd/decimal128.o
|
||||||
|
|
||||||
#########################################################
|
#########################################################
|
||||||
# Linux user emulator target
|
# Linux user emulator target
|
||||||
|
|
||||||
@@ -102,7 +108,8 @@ endif #CONFIG_LINUX_USER
|
|||||||
|
|
||||||
ifdef CONFIG_BSD_USER
|
ifdef CONFIG_BSD_USER
|
||||||
|
|
||||||
QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ABI_DIR)
|
QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ABI_DIR) \
|
||||||
|
-I$(SRC_PATH)/bsd-user/$(HOST_VARIANT_DIR)
|
||||||
|
|
||||||
obj-y += bsd-user/
|
obj-y += bsd-user/
|
||||||
obj-y += gdbstub.o user-exec.o
|
obj-y += gdbstub.o user-exec.o
|
||||||
|
|||||||
43
arch_init.c
43
arch_init.c
@@ -739,7 +739,6 @@ static void migration_end(void)
|
|||||||
XBZRLE_cache_lock();
|
XBZRLE_cache_lock();
|
||||||
if (XBZRLE.cache) {
|
if (XBZRLE.cache) {
|
||||||
cache_fini(XBZRLE.cache);
|
cache_fini(XBZRLE.cache);
|
||||||
g_free(XBZRLE.cache);
|
|
||||||
g_free(XBZRLE.encoded_buf);
|
g_free(XBZRLE.encoded_buf);
|
||||||
g_free(XBZRLE.current_buf);
|
g_free(XBZRLE.current_buf);
|
||||||
XBZRLE.cache = NULL;
|
XBZRLE.cache = NULL;
|
||||||
@@ -1041,17 +1040,15 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
{
|
{
|
||||||
ram_addr_t addr;
|
ram_addr_t addr;
|
||||||
int flags, ret = 0;
|
int flags, ret = 0;
|
||||||
int error;
|
|
||||||
static uint64_t seq_iter;
|
static uint64_t seq_iter;
|
||||||
|
|
||||||
seq_iter++;
|
seq_iter++;
|
||||||
|
|
||||||
if (version_id != 4) {
|
if (version_id != 4) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
while (!ret) {
|
||||||
addr = qemu_get_be64(f);
|
addr = qemu_get_be64(f);
|
||||||
|
|
||||||
flags = addr & ~TARGET_PAGE_MASK;
|
flags = addr & ~TARGET_PAGE_MASK;
|
||||||
@@ -1079,7 +1076,6 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
" in != " RAM_ADDR_FMT, id, length,
|
" in != " RAM_ADDR_FMT, id, length,
|
||||||
block->length);
|
block->length);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto done;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1089,21 +1085,22 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
error_report("Unknown ramblock \"%s\", cannot "
|
error_report("Unknown ramblock \"%s\", cannot "
|
||||||
"accept migration", id);
|
"accept migration", id);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto done;
|
}
|
||||||
|
if (ret) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
total_ram_bytes -= length;
|
total_ram_bytes -= length;
|
||||||
}
|
}
|
||||||
}
|
} else if (flags & RAM_SAVE_FLAG_COMPRESS) {
|
||||||
|
|
||||||
if (flags & RAM_SAVE_FLAG_COMPRESS) {
|
|
||||||
void *host;
|
void *host;
|
||||||
uint8_t ch;
|
uint8_t ch;
|
||||||
|
|
||||||
host = host_from_stream_offset(f, addr, flags);
|
host = host_from_stream_offset(f, addr, flags);
|
||||||
if (!host) {
|
if (!host) {
|
||||||
|
error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto done;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ch = qemu_get_byte(f);
|
ch = qemu_get_byte(f);
|
||||||
@@ -1113,33 +1110,39 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
|
|
||||||
host = host_from_stream_offset(f, addr, flags);
|
host = host_from_stream_offset(f, addr, flags);
|
||||||
if (!host) {
|
if (!host) {
|
||||||
|
error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto done;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
|
qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
|
||||||
} else if (flags & RAM_SAVE_FLAG_XBZRLE) {
|
} else if (flags & RAM_SAVE_FLAG_XBZRLE) {
|
||||||
void *host = host_from_stream_offset(f, addr, flags);
|
void *host = host_from_stream_offset(f, addr, flags);
|
||||||
if (!host) {
|
if (!host) {
|
||||||
|
error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto done;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (load_xbzrle(f, addr, host) < 0) {
|
if (load_xbzrle(f, addr, host) < 0) {
|
||||||
|
error_report("Failed to decompress XBZRLE page at "
|
||||||
|
RAM_ADDR_FMT, addr);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto done;
|
break;
|
||||||
}
|
}
|
||||||
} else if (flags & RAM_SAVE_FLAG_HOOK) {
|
} else if (flags & RAM_SAVE_FLAG_HOOK) {
|
||||||
ram_control_load_hook(f, flags);
|
ram_control_load_hook(f, flags);
|
||||||
|
} else if (flags & RAM_SAVE_FLAG_EOS) {
|
||||||
|
/* normal exit */
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
error_report("Unknown migration flags: %#x", flags);
|
||||||
|
ret = -EINVAL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
error = qemu_file_get_error(f);
|
ret = qemu_file_get_error(f);
|
||||||
if (error) {
|
}
|
||||||
ret = error;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
} while (!(flags & RAM_SAVE_FLAG_EOS));
|
|
||||||
|
|
||||||
done:
|
|
||||||
DPRINTF("Completed load of VM with exit code %d seq iteration "
|
DPRINTF("Completed load of VM with exit code %d seq iteration "
|
||||||
"%" PRIu64 "\n", ret, seq_iter);
|
"%" PRIu64 "\n", ret, seq_iter);
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
14
async.c
14
async.c
@@ -117,15 +117,21 @@ void qemu_bh_schedule_idle(QEMUBH *bh)
|
|||||||
|
|
||||||
void qemu_bh_schedule(QEMUBH *bh)
|
void qemu_bh_schedule(QEMUBH *bh)
|
||||||
{
|
{
|
||||||
|
AioContext *ctx;
|
||||||
|
|
||||||
if (bh->scheduled)
|
if (bh->scheduled)
|
||||||
return;
|
return;
|
||||||
|
ctx = bh->ctx;
|
||||||
bh->idle = 0;
|
bh->idle = 0;
|
||||||
/* Make sure that idle & any writes needed by the callback are done
|
/* Make sure that:
|
||||||
* before the locations are read in the aio_bh_poll.
|
* 1. idle & any writes needed by the callback are done before the
|
||||||
|
* locations are read in the aio_bh_poll.
|
||||||
|
* 2. ctx is loaded before scheduled is set and the callback has a chance
|
||||||
|
* to execute.
|
||||||
*/
|
*/
|
||||||
smp_wmb();
|
smp_mb();
|
||||||
bh->scheduled = 1;
|
bh->scheduled = 1;
|
||||||
aio_notify(bh->ctx);
|
aio_notify(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -815,10 +815,8 @@ static void alsa_fini_out (HWVoiceOut *hw)
|
|||||||
ldebug ("alsa_fini\n");
|
ldebug ("alsa_fini\n");
|
||||||
alsa_anal_close (&alsa->handle, &alsa->pollhlp);
|
alsa_anal_close (&alsa->handle, &alsa->pollhlp);
|
||||||
|
|
||||||
if (alsa->pcm_buf) {
|
g_free(alsa->pcm_buf);
|
||||||
g_free (alsa->pcm_buf);
|
alsa->pcm_buf = NULL;
|
||||||
alsa->pcm_buf = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int alsa_init_out (HWVoiceOut *hw, struct audsettings *as)
|
static int alsa_init_out (HWVoiceOut *hw, struct audsettings *as)
|
||||||
@@ -978,10 +976,8 @@ static void alsa_fini_in (HWVoiceIn *hw)
|
|||||||
|
|
||||||
alsa_anal_close (&alsa->handle, &alsa->pollhlp);
|
alsa_anal_close (&alsa->handle, &alsa->pollhlp);
|
||||||
|
|
||||||
if (alsa->pcm_buf) {
|
g_free(alsa->pcm_buf);
|
||||||
g_free (alsa->pcm_buf);
|
alsa->pcm_buf = NULL;
|
||||||
alsa->pcm_buf = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int alsa_run_in (HWVoiceIn *hw)
|
static int alsa_run_in (HWVoiceIn *hw)
|
||||||
|
|||||||
@@ -71,10 +71,7 @@ static void glue (audio_init_nb_voices_, TYPE) (struct audio_driver *drv)
|
|||||||
|
|
||||||
static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw)
|
static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw)
|
||||||
{
|
{
|
||||||
if (HWBUF) {
|
g_free (HWBUF);
|
||||||
g_free (HWBUF);
|
|
||||||
}
|
|
||||||
|
|
||||||
HWBUF = NULL;
|
HWBUF = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,9 +89,7 @@ static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw)
|
|||||||
|
|
||||||
static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw)
|
static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw)
|
||||||
{
|
{
|
||||||
if (sw->buf) {
|
g_free (sw->buf);
|
||||||
g_free (sw->buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sw->rate) {
|
if (sw->rate) {
|
||||||
st_rate_stop (sw->rate);
|
st_rate_stop (sw->rate);
|
||||||
@@ -172,10 +167,8 @@ static int glue (audio_pcm_sw_init_, TYPE) (
|
|||||||
static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)
|
static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)
|
||||||
{
|
{
|
||||||
glue (audio_pcm_sw_free_resources_, TYPE) (sw);
|
glue (audio_pcm_sw_free_resources_, TYPE) (sw);
|
||||||
if (sw->name) {
|
g_free (sw->name);
|
||||||
g_free (sw->name);
|
sw->name = NULL;
|
||||||
sw->name = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void glue (audio_pcm_hw_add_sw_, TYPE) (HW *hw, SW *sw)
|
static void glue (audio_pcm_hw_add_sw_, TYPE) (HW *hw, SW *sw)
|
||||||
|
|||||||
@@ -736,10 +736,8 @@ static void oss_fini_in (HWVoiceIn *hw)
|
|||||||
|
|
||||||
oss_anal_close (&oss->fd);
|
oss_anal_close (&oss->fd);
|
||||||
|
|
||||||
if (oss->pcm_buf) {
|
g_free(oss->pcm_buf);
|
||||||
g_free (oss->pcm_buf);
|
oss->pcm_buf = NULL;
|
||||||
oss->pcm_buf = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int oss_run_in (HWVoiceIn *hw)
|
static int oss_run_in (HWVoiceIn *hw)
|
||||||
|
|||||||
@@ -629,6 +629,7 @@ static int block_save_setup(QEMUFile *f, void *opaque)
|
|||||||
block_mig_state.submitted, block_mig_state.transferred);
|
block_mig_state.submitted, block_mig_state.transferred);
|
||||||
|
|
||||||
qemu_mutex_lock_iothread();
|
qemu_mutex_lock_iothread();
|
||||||
|
init_blk_migration(f);
|
||||||
|
|
||||||
/* start track dirty blocks */
|
/* start track dirty blocks */
|
||||||
ret = set_dirty_tracking();
|
ret = set_dirty_tracking();
|
||||||
@@ -638,8 +639,6 @@ static int block_save_setup(QEMUFile *f, void *opaque)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
init_blk_migration(f);
|
|
||||||
|
|
||||||
qemu_mutex_unlock_iothread();
|
qemu_mutex_unlock_iothread();
|
||||||
|
|
||||||
ret = flush_blks(f);
|
ret = flush_blks(f);
|
||||||
|
|||||||
243
block.c
243
block.c
@@ -179,6 +179,7 @@ void bdrv_io_limits_enable(BlockDriverState *bs)
|
|||||||
{
|
{
|
||||||
assert(!bs->io_limits_enabled);
|
assert(!bs->io_limits_enabled);
|
||||||
throttle_init(&bs->throttle_state,
|
throttle_init(&bs->throttle_state,
|
||||||
|
bdrv_get_aio_context(bs),
|
||||||
QEMU_CLOCK_VIRTUAL,
|
QEMU_CLOCK_VIRTUAL,
|
||||||
bdrv_throttle_read_timer_cb,
|
bdrv_throttle_read_timer_cb,
|
||||||
bdrv_throttle_write_timer_cb,
|
bdrv_throttle_write_timer_cb,
|
||||||
@@ -363,6 +364,7 @@ BlockDriverState *bdrv_new(const char *device_name, Error **errp)
|
|||||||
qemu_co_queue_init(&bs->throttled_reqs[0]);
|
qemu_co_queue_init(&bs->throttled_reqs[0]);
|
||||||
qemu_co_queue_init(&bs->throttled_reqs[1]);
|
qemu_co_queue_init(&bs->throttled_reqs[1]);
|
||||||
bs->refcnt = 1;
|
bs->refcnt = 1;
|
||||||
|
bs->aio_context = qemu_get_aio_context();
|
||||||
|
|
||||||
return bs;
|
return bs;
|
||||||
}
|
}
|
||||||
@@ -422,7 +424,7 @@ BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
|
|||||||
typedef struct CreateCo {
|
typedef struct CreateCo {
|
||||||
BlockDriver *drv;
|
BlockDriver *drv;
|
||||||
char *filename;
|
char *filename;
|
||||||
QEMUOptionParameter *options;
|
QemuOpts *opts;
|
||||||
int ret;
|
int ret;
|
||||||
Error *err;
|
Error *err;
|
||||||
} CreateCo;
|
} CreateCo;
|
||||||
@@ -435,7 +437,7 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
|
|||||||
CreateCo *cco = opaque;
|
CreateCo *cco = opaque;
|
||||||
assert(cco->drv);
|
assert(cco->drv);
|
||||||
|
|
||||||
ret = cco->drv->bdrv_create(cco->filename, cco->options, &local_err);
|
ret = cco->drv->bdrv_create(cco->filename, cco->opts, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_propagate(&cco->err, local_err);
|
error_propagate(&cco->err, local_err);
|
||||||
}
|
}
|
||||||
@@ -443,7 +445,7 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int bdrv_create(BlockDriver *drv, const char* filename,
|
int bdrv_create(BlockDriver *drv, const char* filename,
|
||||||
QEMUOptionParameter *options, Error **errp)
|
QemuOpts *opts, Error **errp)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -451,7 +453,7 @@ int bdrv_create(BlockDriver *drv, const char* filename,
|
|||||||
CreateCo cco = {
|
CreateCo cco = {
|
||||||
.drv = drv,
|
.drv = drv,
|
||||||
.filename = g_strdup(filename),
|
.filename = g_strdup(filename),
|
||||||
.options = options,
|
.opts = opts,
|
||||||
.ret = NOT_DONE,
|
.ret = NOT_DONE,
|
||||||
.err = NULL,
|
.err = NULL,
|
||||||
};
|
};
|
||||||
@@ -487,8 +489,7 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bdrv_create_file(const char* filename, QEMUOptionParameter *options,
|
int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
BlockDriver *drv;
|
BlockDriver *drv;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
@@ -500,7 +501,7 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options,
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bdrv_create(drv, filename, options, &local_err);
|
ret = bdrv_create(drv, filename, opts, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
}
|
}
|
||||||
@@ -1245,7 +1246,7 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
|
|||||||
char *tmp_filename = g_malloc0(PATH_MAX + 1);
|
char *tmp_filename = g_malloc0(PATH_MAX + 1);
|
||||||
int64_t total_size;
|
int64_t total_size;
|
||||||
BlockDriver *bdrv_qcow2;
|
BlockDriver *bdrv_qcow2;
|
||||||
QEMUOptionParameter *create_options;
|
QemuOpts *opts = NULL;
|
||||||
QDict *snapshot_options;
|
QDict *snapshot_options;
|
||||||
BlockDriverState *bs_snapshot;
|
BlockDriverState *bs_snapshot;
|
||||||
Error *local_err;
|
Error *local_err;
|
||||||
@@ -1270,13 +1271,11 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bdrv_qcow2 = bdrv_find_format("qcow2");
|
bdrv_qcow2 = bdrv_find_format("qcow2");
|
||||||
create_options = parse_option_parameters("", bdrv_qcow2->create_options,
|
opts = qemu_opts_create(bdrv_qcow2->create_opts, NULL, 0,
|
||||||
NULL);
|
&error_abort);
|
||||||
|
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size);
|
||||||
set_option_parameter_int(create_options, BLOCK_OPT_SIZE, total_size);
|
ret = bdrv_create(bdrv_qcow2, tmp_filename, opts, &local_err);
|
||||||
|
qemu_opts_del(opts);
|
||||||
ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options, &local_err);
|
|
||||||
free_option_parameters(create_options);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_setg_errno(errp, -ret, "Could not create temporary overlay "
|
error_setg_errno(errp, -ret, "Could not create temporary overlay "
|
||||||
"'%s': %s", tmp_filename,
|
"'%s': %s", tmp_filename,
|
||||||
@@ -1856,7 +1855,11 @@ void bdrv_close_all(void)
|
|||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
|
|
||||||
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
|
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
|
||||||
|
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||||
|
|
||||||
|
aio_context_acquire(aio_context);
|
||||||
bdrv_close(bs);
|
bdrv_close(bs);
|
||||||
|
aio_context_release(aio_context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1881,17 +1884,6 @@ static bool bdrv_requests_pending(BlockDriverState *bs)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool bdrv_requests_pending_all(void)
|
|
||||||
{
|
|
||||||
BlockDriverState *bs;
|
|
||||||
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
|
|
||||||
if (bdrv_requests_pending(bs)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait for pending requests to complete across all BlockDriverStates
|
* Wait for pending requests to complete across all BlockDriverStates
|
||||||
*
|
*
|
||||||
@@ -1911,12 +1903,20 @@ void bdrv_drain_all(void)
|
|||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
|
|
||||||
while (busy) {
|
while (busy) {
|
||||||
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
|
busy = false;
|
||||||
bdrv_start_throttled_reqs(bs);
|
|
||||||
}
|
|
||||||
|
|
||||||
busy = bdrv_requests_pending_all();
|
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
|
||||||
busy |= aio_poll(qemu_get_aio_context(), busy);
|
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||||
|
bool bs_busy;
|
||||||
|
|
||||||
|
aio_context_acquire(aio_context);
|
||||||
|
bdrv_start_throttled_reqs(bs);
|
||||||
|
bs_busy = bdrv_requests_pending(bs);
|
||||||
|
bs_busy |= aio_poll(aio_context, bs_busy);
|
||||||
|
aio_context_release(aio_context);
|
||||||
|
|
||||||
|
busy |= bs_busy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2352,12 +2352,17 @@ int bdrv_commit_all(void)
|
|||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
|
|
||||||
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
|
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
|
||||||
|
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||||
|
|
||||||
|
aio_context_acquire(aio_context);
|
||||||
if (bs->drv && bs->backing_hd) {
|
if (bs->drv && bs->backing_hd) {
|
||||||
int ret = bdrv_commit(bs);
|
int ret = bdrv_commit(bs);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
aio_context_release(aio_context);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
aio_context_release(aio_context);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2775,10 +2780,12 @@ static int bdrv_prwv_co(BlockDriverState *bs, int64_t offset,
|
|||||||
/* Fast-path if already in coroutine context */
|
/* Fast-path if already in coroutine context */
|
||||||
bdrv_rw_co_entry(&rwco);
|
bdrv_rw_co_entry(&rwco);
|
||||||
} else {
|
} else {
|
||||||
|
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||||
|
|
||||||
co = qemu_coroutine_create(bdrv_rw_co_entry);
|
co = qemu_coroutine_create(bdrv_rw_co_entry);
|
||||||
qemu_coroutine_enter(co, &rwco);
|
qemu_coroutine_enter(co, &rwco);
|
||||||
while (rwco.ret == NOT_DONE) {
|
while (rwco.ret == NOT_DONE) {
|
||||||
qemu_aio_wait();
|
aio_poll(aio_context, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rwco.ret;
|
return rwco.ret;
|
||||||
@@ -3831,10 +3838,15 @@ int bdrv_flush_all(void)
|
|||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
|
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
|
||||||
int ret = bdrv_flush(bs);
|
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
aio_context_acquire(aio_context);
|
||||||
|
ret = bdrv_flush(bs);
|
||||||
if (ret < 0 && !result) {
|
if (ret < 0 && !result) {
|
||||||
result = ret;
|
result = ret;
|
||||||
}
|
}
|
||||||
|
aio_context_release(aio_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -4025,10 +4037,12 @@ int64_t bdrv_get_block_status(BlockDriverState *bs, int64_t sector_num,
|
|||||||
/* Fast-path if already in coroutine context */
|
/* Fast-path if already in coroutine context */
|
||||||
bdrv_get_block_status_co_entry(&data);
|
bdrv_get_block_status_co_entry(&data);
|
||||||
} else {
|
} else {
|
||||||
|
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||||
|
|
||||||
co = qemu_coroutine_create(bdrv_get_block_status_co_entry);
|
co = qemu_coroutine_create(bdrv_get_block_status_co_entry);
|
||||||
qemu_coroutine_enter(co, &data);
|
qemu_coroutine_enter(co, &data);
|
||||||
while (!data.done) {
|
while (!data.done) {
|
||||||
qemu_aio_wait();
|
aio_poll(aio_context, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return data.ret;
|
return data.ret;
|
||||||
@@ -4621,7 +4635,7 @@ static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
|
|||||||
acb->is_write = is_write;
|
acb->is_write = is_write;
|
||||||
acb->qiov = qiov;
|
acb->qiov = qiov;
|
||||||
acb->bounce = qemu_blockalign(bs, qiov->size);
|
acb->bounce = qemu_blockalign(bs, qiov->size);
|
||||||
acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
|
acb->bh = aio_bh_new(bdrv_get_aio_context(bs), bdrv_aio_bh_cb, acb);
|
||||||
|
|
||||||
if (is_write) {
|
if (is_write) {
|
||||||
qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size);
|
qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size);
|
||||||
@@ -4660,13 +4674,14 @@ typedef struct BlockDriverAIOCBCoroutine {
|
|||||||
|
|
||||||
static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb)
|
static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb)
|
||||||
{
|
{
|
||||||
|
AioContext *aio_context = bdrv_get_aio_context(blockacb->bs);
|
||||||
BlockDriverAIOCBCoroutine *acb =
|
BlockDriverAIOCBCoroutine *acb =
|
||||||
container_of(blockacb, BlockDriverAIOCBCoroutine, common);
|
container_of(blockacb, BlockDriverAIOCBCoroutine, common);
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
|
||||||
acb->done = &done;
|
acb->done = &done;
|
||||||
while (!done) {
|
while (!done) {
|
||||||
qemu_aio_wait();
|
aio_poll(aio_context, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4703,7 +4718,7 @@ static void coroutine_fn bdrv_co_do_rw(void *opaque)
|
|||||||
acb->req.nb_sectors, acb->req.qiov, acb->req.flags);
|
acb->req.nb_sectors, acb->req.qiov, acb->req.flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
|
acb->bh = aio_bh_new(bdrv_get_aio_context(bs), bdrv_co_em_bh, acb);
|
||||||
qemu_bh_schedule(acb->bh);
|
qemu_bh_schedule(acb->bh);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4739,7 +4754,7 @@ static void coroutine_fn bdrv_aio_flush_co_entry(void *opaque)
|
|||||||
BlockDriverState *bs = acb->common.bs;
|
BlockDriverState *bs = acb->common.bs;
|
||||||
|
|
||||||
acb->req.error = bdrv_co_flush(bs);
|
acb->req.error = bdrv_co_flush(bs);
|
||||||
acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
|
acb->bh = aio_bh_new(bdrv_get_aio_context(bs), bdrv_co_em_bh, acb);
|
||||||
qemu_bh_schedule(acb->bh);
|
qemu_bh_schedule(acb->bh);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4766,7 +4781,7 @@ static void coroutine_fn bdrv_aio_discard_co_entry(void *opaque)
|
|||||||
BlockDriverState *bs = acb->common.bs;
|
BlockDriverState *bs = acb->common.bs;
|
||||||
|
|
||||||
acb->req.error = bdrv_co_discard(bs, acb->req.sector, acb->req.nb_sectors);
|
acb->req.error = bdrv_co_discard(bs, acb->req.sector, acb->req.nb_sectors);
|
||||||
acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
|
acb->bh = aio_bh_new(bdrv_get_aio_context(bs), bdrv_co_em_bh, acb);
|
||||||
qemu_bh_schedule(acb->bh);
|
qemu_bh_schedule(acb->bh);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4977,7 +4992,11 @@ void bdrv_invalidate_cache_all(Error **errp)
|
|||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
|
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
|
||||||
|
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||||
|
|
||||||
|
aio_context_acquire(aio_context);
|
||||||
bdrv_invalidate_cache(bs, &local_err);
|
bdrv_invalidate_cache(bs, &local_err);
|
||||||
|
aio_context_release(aio_context);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
return;
|
return;
|
||||||
@@ -4990,7 +5009,11 @@ void bdrv_clear_incoming_migration_all(void)
|
|||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
|
|
||||||
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
|
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
|
||||||
|
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||||
|
|
||||||
|
aio_context_acquire(aio_context);
|
||||||
bs->open_flags = bs->open_flags & ~(BDRV_O_INCOMING);
|
bs->open_flags = bs->open_flags & ~(BDRV_O_INCOMING);
|
||||||
|
aio_context_release(aio_context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5006,10 +5029,12 @@ int bdrv_flush(BlockDriverState *bs)
|
|||||||
/* Fast-path if already in coroutine context */
|
/* Fast-path if already in coroutine context */
|
||||||
bdrv_flush_co_entry(&rwco);
|
bdrv_flush_co_entry(&rwco);
|
||||||
} else {
|
} else {
|
||||||
|
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||||
|
|
||||||
co = qemu_coroutine_create(bdrv_flush_co_entry);
|
co = qemu_coroutine_create(bdrv_flush_co_entry);
|
||||||
qemu_coroutine_enter(co, &rwco);
|
qemu_coroutine_enter(co, &rwco);
|
||||||
while (rwco.ret == NOT_DONE) {
|
while (rwco.ret == NOT_DONE) {
|
||||||
qemu_aio_wait();
|
aio_poll(aio_context, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5119,10 +5144,12 @@ int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
|
|||||||
/* Fast-path if already in coroutine context */
|
/* Fast-path if already in coroutine context */
|
||||||
bdrv_discard_co_entry(&rwco);
|
bdrv_discard_co_entry(&rwco);
|
||||||
} else {
|
} else {
|
||||||
|
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||||
|
|
||||||
co = qemu_coroutine_create(bdrv_discard_co_entry);
|
co = qemu_coroutine_create(bdrv_discard_co_entry);
|
||||||
qemu_coroutine_enter(co, &rwco);
|
qemu_coroutine_enter(co, &rwco);
|
||||||
while (rwco.ret == NOT_DONE) {
|
while (rwco.ret == NOT_DONE) {
|
||||||
qemu_aio_wait();
|
aio_poll(aio_context, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5489,8 +5516,10 @@ void bdrv_img_create(const char *filename, const char *fmt,
|
|||||||
char *options, uint64_t img_size, int flags,
|
char *options, uint64_t img_size, int flags,
|
||||||
Error **errp, bool quiet)
|
Error **errp, bool quiet)
|
||||||
{
|
{
|
||||||
QEMUOptionParameter *param = NULL, *create_options = NULL;
|
QemuOptsList *create_opts = NULL;
|
||||||
QEMUOptionParameter *backing_fmt, *backing_file, *size;
|
QemuOpts *opts = NULL;
|
||||||
|
const char *backing_fmt, *backing_file;
|
||||||
|
int64_t size;
|
||||||
BlockDriver *drv, *proto_drv;
|
BlockDriver *drv, *proto_drv;
|
||||||
BlockDriver *backing_drv = NULL;
|
BlockDriver *backing_drv = NULL;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
@@ -5509,28 +5538,23 @@ void bdrv_img_create(const char *filename, const char *fmt,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
create_options = append_option_parameters(create_options,
|
create_opts = qemu_opts_append(create_opts, drv->create_opts);
|
||||||
drv->create_options);
|
create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
|
||||||
create_options = append_option_parameters(create_options,
|
|
||||||
proto_drv->create_options);
|
|
||||||
|
|
||||||
/* Create parameter list with default values */
|
/* Create parameter list with default values */
|
||||||
param = parse_option_parameters("", create_options, param);
|
opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
|
||||||
|
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, img_size);
|
||||||
set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size);
|
|
||||||
|
|
||||||
/* Parse -o options */
|
/* Parse -o options */
|
||||||
if (options) {
|
if (options) {
|
||||||
param = parse_option_parameters(options, create_options, param);
|
if (qemu_opts_do_parse(opts, options, NULL) != 0) {
|
||||||
if (param == NULL) {
|
error_setg(errp, "Invalid options for file format '%s'", fmt);
|
||||||
error_setg(errp, "Invalid options for file format '%s'.", fmt);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base_filename) {
|
if (base_filename) {
|
||||||
if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE,
|
if (qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, base_filename)) {
|
||||||
base_filename)) {
|
|
||||||
error_setg(errp, "Backing file not supported for file format '%s'",
|
error_setg(errp, "Backing file not supported for file format '%s'",
|
||||||
fmt);
|
fmt);
|
||||||
goto out;
|
goto out;
|
||||||
@@ -5538,37 +5562,37 @@ void bdrv_img_create(const char *filename, const char *fmt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (base_fmt) {
|
if (base_fmt) {
|
||||||
if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) {
|
if (qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, base_fmt)) {
|
||||||
error_setg(errp, "Backing file format not supported for file "
|
error_setg(errp, "Backing file format not supported for file "
|
||||||
"format '%s'", fmt);
|
"format '%s'", fmt);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
|
backing_file = qemu_opt_get(opts, BLOCK_OPT_BACKING_FILE);
|
||||||
if (backing_file && backing_file->value.s) {
|
if (backing_file) {
|
||||||
if (!strcmp(filename, backing_file->value.s)) {
|
if (!strcmp(filename, backing_file)) {
|
||||||
error_setg(errp, "Error: Trying to create an image with the "
|
error_setg(errp, "Error: Trying to create an image with the "
|
||||||
"same filename as the backing file");
|
"same filename as the backing file");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
|
backing_fmt = qemu_opt_get(opts, BLOCK_OPT_BACKING_FMT);
|
||||||
if (backing_fmt && backing_fmt->value.s) {
|
if (backing_fmt) {
|
||||||
backing_drv = bdrv_find_format(backing_fmt->value.s);
|
backing_drv = bdrv_find_format(backing_fmt);
|
||||||
if (!backing_drv) {
|
if (!backing_drv) {
|
||||||
error_setg(errp, "Unknown backing file format '%s'",
|
error_setg(errp, "Unknown backing file format '%s'",
|
||||||
backing_fmt->value.s);
|
backing_fmt);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The size for the image must always be specified, with one exception:
|
// The size for the image must always be specified, with one exception:
|
||||||
// If we are using a backing file, we can obtain the size from there
|
// If we are using a backing file, we can obtain the size from there
|
||||||
size = get_option_parameter(param, BLOCK_OPT_SIZE);
|
size = qemu_opt_get_size(opts, BLOCK_OPT_SIZE, 0);
|
||||||
if (size && size->value.n == -1) {
|
if (size == -1) {
|
||||||
if (backing_file && backing_file->value.s) {
|
if (backing_file) {
|
||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
char buf[32];
|
char buf[32];
|
||||||
@@ -5579,11 +5603,11 @@ void bdrv_img_create(const char *filename, const char *fmt,
|
|||||||
flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
|
flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
|
||||||
|
|
||||||
bs = NULL;
|
bs = NULL;
|
||||||
ret = bdrv_open(&bs, backing_file->value.s, NULL, NULL, back_flags,
|
ret = bdrv_open(&bs, backing_file, NULL, NULL, back_flags,
|
||||||
backing_drv, &local_err);
|
backing_drv, &local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_setg_errno(errp, -ret, "Could not open '%s': %s",
|
error_setg_errno(errp, -ret, "Could not open '%s': %s",
|
||||||
backing_file->value.s,
|
backing_file,
|
||||||
error_get_pretty(local_err));
|
error_get_pretty(local_err));
|
||||||
error_free(local_err);
|
error_free(local_err);
|
||||||
local_err = NULL;
|
local_err = NULL;
|
||||||
@@ -5593,7 +5617,7 @@ void bdrv_img_create(const char *filename, const char *fmt,
|
|||||||
size *= 512;
|
size *= 512;
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "%" PRId64, size);
|
snprintf(buf, sizeof(buf), "%" PRId64, size);
|
||||||
set_option_parameter(param, BLOCK_OPT_SIZE, buf);
|
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size);
|
||||||
|
|
||||||
bdrv_unref(bs);
|
bdrv_unref(bs);
|
||||||
} else {
|
} else {
|
||||||
@@ -5604,16 +5628,18 @@ void bdrv_img_create(const char *filename, const char *fmt,
|
|||||||
|
|
||||||
if (!quiet) {
|
if (!quiet) {
|
||||||
printf("Formatting '%s', fmt=%s ", filename, fmt);
|
printf("Formatting '%s', fmt=%s ", filename, fmt);
|
||||||
print_option_parameters(param);
|
qemu_opts_print(opts);
|
||||||
puts("");
|
puts("");
|
||||||
}
|
}
|
||||||
ret = bdrv_create(drv, filename, param, &local_err);
|
|
||||||
|
ret = bdrv_create(drv, filename, opts, &local_err);
|
||||||
|
|
||||||
if (ret == -EFBIG) {
|
if (ret == -EFBIG) {
|
||||||
/* This is generally a better message than whatever the driver would
|
/* This is generally a better message than whatever the driver would
|
||||||
* deliver (especially because of the cluster_size_hint), since that
|
* deliver (especially because of the cluster_size_hint), since that
|
||||||
* is most probably not much different from "image too large". */
|
* is most probably not much different from "image too large". */
|
||||||
const char *cluster_size_hint = "";
|
const char *cluster_size_hint = "";
|
||||||
if (get_option_parameter(create_options, BLOCK_OPT_CLUSTER_SIZE)) {
|
if (qemu_opt_get_size(opts, BLOCK_OPT_CLUSTER_SIZE, 0)) {
|
||||||
cluster_size_hint = " (try using a larger cluster size)";
|
cluster_size_hint = " (try using a larger cluster size)";
|
||||||
}
|
}
|
||||||
error_setg(errp, "The image size is too large for file format '%s'"
|
error_setg(errp, "The image size is too large for file format '%s'"
|
||||||
@@ -5623,9 +5649,8 @@ void bdrv_img_create(const char *filename, const char *fmt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free_option_parameters(create_options);
|
qemu_opts_del(opts);
|
||||||
free_option_parameters(param);
|
qemu_opts_free(create_opts);
|
||||||
|
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
}
|
}
|
||||||
@@ -5633,8 +5658,66 @@ out:
|
|||||||
|
|
||||||
AioContext *bdrv_get_aio_context(BlockDriverState *bs)
|
AioContext *bdrv_get_aio_context(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
/* Currently BlockDriverState always uses the main loop AioContext */
|
return bs->aio_context;
|
||||||
return qemu_get_aio_context();
|
}
|
||||||
|
|
||||||
|
void bdrv_detach_aio_context(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
if (!bs->drv) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bs->io_limits_enabled) {
|
||||||
|
throttle_detach_aio_context(&bs->throttle_state);
|
||||||
|
}
|
||||||
|
if (bs->drv->bdrv_detach_aio_context) {
|
||||||
|
bs->drv->bdrv_detach_aio_context(bs);
|
||||||
|
}
|
||||||
|
if (bs->file) {
|
||||||
|
bdrv_detach_aio_context(bs->file);
|
||||||
|
}
|
||||||
|
if (bs->backing_hd) {
|
||||||
|
bdrv_detach_aio_context(bs->backing_hd);
|
||||||
|
}
|
||||||
|
|
||||||
|
bs->aio_context = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bdrv_attach_aio_context(BlockDriverState *bs,
|
||||||
|
AioContext *new_context)
|
||||||
|
{
|
||||||
|
if (!bs->drv) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bs->aio_context = new_context;
|
||||||
|
|
||||||
|
if (bs->backing_hd) {
|
||||||
|
bdrv_attach_aio_context(bs->backing_hd, new_context);
|
||||||
|
}
|
||||||
|
if (bs->file) {
|
||||||
|
bdrv_attach_aio_context(bs->file, new_context);
|
||||||
|
}
|
||||||
|
if (bs->drv->bdrv_attach_aio_context) {
|
||||||
|
bs->drv->bdrv_attach_aio_context(bs, new_context);
|
||||||
|
}
|
||||||
|
if (bs->io_limits_enabled) {
|
||||||
|
throttle_attach_aio_context(&bs->throttle_state, new_context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
|
||||||
|
{
|
||||||
|
bdrv_drain_all(); /* ensure there are no in-flight requests */
|
||||||
|
|
||||||
|
bdrv_detach_aio_context(bs);
|
||||||
|
|
||||||
|
/* This function executes in the old AioContext so acquire the new one in
|
||||||
|
* case it runs in a different thread.
|
||||||
|
*/
|
||||||
|
aio_context_acquire(new_context);
|
||||||
|
bdrv_attach_aio_context(bs, new_context);
|
||||||
|
aio_context_release(new_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bdrv_add_before_write_notifier(BlockDriverState *bs,
|
void bdrv_add_before_write_notifier(BlockDriverState *bs,
|
||||||
@@ -5643,12 +5726,12 @@ void bdrv_add_before_write_notifier(BlockDriverState *bs,
|
|||||||
notifier_with_return_list_add(&bs->before_write_notifiers, notifier);
|
notifier_with_return_list_add(&bs->before_write_notifiers, notifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bdrv_amend_options(BlockDriverState *bs, QEMUOptionParameter *options)
|
int bdrv_amend_options(BlockDriverState *bs, QemuOpts *opts)
|
||||||
{
|
{
|
||||||
if (bs->drv->bdrv_amend_options == NULL) {
|
if (!bs->drv->bdrv_amend_options) {
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
return bs->drv->bdrv_amend_options(bs, options);
|
return bs->drv->bdrv_amend_options(bs, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function will be called by the bdrv_recurse_is_first_non_filter method
|
/* This function will be called by the bdrv_recurse_is_first_non_filter method
|
||||||
|
|||||||
@@ -471,7 +471,7 @@ static BlockDriverAIOCB *inject_error(BlockDriverState *bs,
|
|||||||
acb = qemu_aio_get(&blkdebug_aiocb_info, bs, cb, opaque);
|
acb = qemu_aio_get(&blkdebug_aiocb_info, bs, cb, opaque);
|
||||||
acb->ret = -error;
|
acb->ret = -error;
|
||||||
|
|
||||||
bh = qemu_bh_new(error_callback_bh, acb);
|
bh = aio_bh_new(bdrv_get_aio_context(bs), error_callback_bh, acb);
|
||||||
acb->bh = bh;
|
acb->bh = bh;
|
||||||
qemu_bh_schedule(bh);
|
qemu_bh_schedule(bh);
|
||||||
|
|
||||||
|
|||||||
@@ -39,12 +39,13 @@ struct BlkverifyAIOCB {
|
|||||||
static void blkverify_aio_cancel(BlockDriverAIOCB *blockacb)
|
static void blkverify_aio_cancel(BlockDriverAIOCB *blockacb)
|
||||||
{
|
{
|
||||||
BlkverifyAIOCB *acb = (BlkverifyAIOCB *)blockacb;
|
BlkverifyAIOCB *acb = (BlkverifyAIOCB *)blockacb;
|
||||||
|
AioContext *aio_context = bdrv_get_aio_context(blockacb->bs);
|
||||||
bool finished = false;
|
bool finished = false;
|
||||||
|
|
||||||
/* Wait until request completes, invokes its callback, and frees itself */
|
/* Wait until request completes, invokes its callback, and frees itself */
|
||||||
acb->finished = &finished;
|
acb->finished = &finished;
|
||||||
while (!finished) {
|
while (!finished) {
|
||||||
qemu_aio_wait();
|
aio_poll(aio_context, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,7 +229,8 @@ static void blkverify_aio_cb(void *opaque, int ret)
|
|||||||
acb->verify(acb);
|
acb->verify(acb);
|
||||||
}
|
}
|
||||||
|
|
||||||
acb->bh = qemu_bh_new(blkverify_aio_bh, acb);
|
acb->bh = aio_bh_new(bdrv_get_aio_context(acb->common.bs),
|
||||||
|
blkverify_aio_bh, acb);
|
||||||
qemu_bh_schedule(acb->bh);
|
qemu_bh_schedule(acb->bh);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -302,21 +304,40 @@ static bool blkverify_recurse_is_first_non_filter(BlockDriverState *bs,
|
|||||||
return bdrv_recurse_is_first_non_filter(s->test_file, candidate);
|
return bdrv_recurse_is_first_non_filter(s->test_file, candidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Propagate AioContext changes to ->test_file */
|
||||||
|
static void blkverify_detach_aio_context(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
BDRVBlkverifyState *s = bs->opaque;
|
||||||
|
|
||||||
|
bdrv_detach_aio_context(s->test_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void blkverify_attach_aio_context(BlockDriverState *bs,
|
||||||
|
AioContext *new_context)
|
||||||
|
{
|
||||||
|
BDRVBlkverifyState *s = bs->opaque;
|
||||||
|
|
||||||
|
bdrv_attach_aio_context(s->test_file, new_context);
|
||||||
|
}
|
||||||
|
|
||||||
static BlockDriver bdrv_blkverify = {
|
static BlockDriver bdrv_blkverify = {
|
||||||
.format_name = "blkverify",
|
.format_name = "blkverify",
|
||||||
.protocol_name = "blkverify",
|
.protocol_name = "blkverify",
|
||||||
.instance_size = sizeof(BDRVBlkverifyState),
|
.instance_size = sizeof(BDRVBlkverifyState),
|
||||||
|
|
||||||
.bdrv_parse_filename = blkverify_parse_filename,
|
.bdrv_parse_filename = blkverify_parse_filename,
|
||||||
.bdrv_file_open = blkverify_open,
|
.bdrv_file_open = blkverify_open,
|
||||||
.bdrv_close = blkverify_close,
|
.bdrv_close = blkverify_close,
|
||||||
.bdrv_getlength = blkverify_getlength,
|
.bdrv_getlength = blkverify_getlength,
|
||||||
|
|
||||||
.bdrv_aio_readv = blkverify_aio_readv,
|
.bdrv_aio_readv = blkverify_aio_readv,
|
||||||
.bdrv_aio_writev = blkverify_aio_writev,
|
.bdrv_aio_writev = blkverify_aio_writev,
|
||||||
.bdrv_aio_flush = blkverify_aio_flush,
|
.bdrv_aio_flush = blkverify_aio_flush,
|
||||||
|
|
||||||
.is_filter = true,
|
.bdrv_attach_aio_context = blkverify_attach_aio_context,
|
||||||
|
.bdrv_detach_aio_context = blkverify_detach_aio_context,
|
||||||
|
|
||||||
|
.is_filter = true,
|
||||||
.bdrv_recurse_is_first_non_filter = blkverify_recurse_is_first_non_filter,
|
.bdrv_recurse_is_first_non_filter = blkverify_recurse_is_first_non_filter,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
52
block/cow.c
52
block/cow.c
@@ -324,31 +324,24 @@ static void cow_close(BlockDriverState *bs)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cow_create(const char *filename, QEMUOptionParameter *options,
|
static int cow_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
struct cow_header_v2 cow_header;
|
struct cow_header_v2 cow_header;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int64_t image_sectors = 0;
|
int64_t image_sectors = 0;
|
||||||
const char *image_filename = NULL;
|
char *image_filename = NULL;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
BlockDriverState *cow_bs;
|
BlockDriverState *cow_bs;
|
||||||
|
|
||||||
/* Read out options */
|
/* Read out options */
|
||||||
while (options && options->name) {
|
image_sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
|
||||||
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
|
image_filename = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
|
||||||
image_sectors = options->value.n / 512;
|
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
|
|
||||||
image_filename = options->value.s;
|
|
||||||
}
|
|
||||||
options++;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = bdrv_create_file(filename, options, &local_err);
|
ret = bdrv_create_file(filename, opts, &local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
return ret;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
cow_bs = NULL;
|
cow_bs = NULL;
|
||||||
@@ -356,7 +349,7 @@ static int cow_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err);
|
BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
return ret;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&cow_header, 0, sizeof(cow_header));
|
memset(&cow_header, 0, sizeof(cow_header));
|
||||||
@@ -389,22 +382,27 @@ static int cow_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
g_free(image_filename);
|
||||||
bdrv_unref(cow_bs);
|
bdrv_unref(cow_bs);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QEMUOptionParameter cow_create_options[] = {
|
static QemuOptsList cow_create_opts = {
|
||||||
{
|
.name = "cow-create-opts",
|
||||||
.name = BLOCK_OPT_SIZE,
|
.head = QTAILQ_HEAD_INITIALIZER(cow_create_opts.head),
|
||||||
.type = OPT_SIZE,
|
.desc = {
|
||||||
.help = "Virtual disk size"
|
{
|
||||||
},
|
.name = BLOCK_OPT_SIZE,
|
||||||
{
|
.type = QEMU_OPT_SIZE,
|
||||||
.name = BLOCK_OPT_BACKING_FILE,
|
.help = "Virtual disk size"
|
||||||
.type = OPT_STRING,
|
},
|
||||||
.help = "File name of a base image"
|
{
|
||||||
},
|
.name = BLOCK_OPT_BACKING_FILE,
|
||||||
{ NULL }
|
.type = QEMU_OPT_STRING,
|
||||||
|
.help = "File name of a base image"
|
||||||
|
},
|
||||||
|
{ /* end of list */ }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_cow = {
|
static BlockDriver bdrv_cow = {
|
||||||
@@ -421,7 +419,7 @@ static BlockDriver bdrv_cow = {
|
|||||||
.bdrv_write = cow_co_write,
|
.bdrv_write = cow_co_write,
|
||||||
.bdrv_co_get_block_status = cow_co_get_block_status,
|
.bdrv_co_get_block_status = cow_co_get_block_status,
|
||||||
|
|
||||||
.create_options = cow_create_options,
|
.create_opts = &cow_create_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void bdrv_cow_init(void)
|
static void bdrv_cow_init(void)
|
||||||
|
|||||||
193
block/curl.c
193
block/curl.c
@@ -110,6 +110,7 @@ typedef struct BDRVCURLState {
|
|||||||
size_t readahead_size;
|
size_t readahead_size;
|
||||||
bool sslverify;
|
bool sslverify;
|
||||||
bool accept_range;
|
bool accept_range;
|
||||||
|
AioContext *aio_context;
|
||||||
} BDRVCURLState;
|
} BDRVCURLState;
|
||||||
|
|
||||||
static void curl_clean_state(CURLState *s);
|
static void curl_clean_state(CURLState *s);
|
||||||
@@ -134,25 +135,29 @@ static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
|
static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
|
||||||
void *s, void *sp)
|
void *userp, void *sp)
|
||||||
{
|
{
|
||||||
|
BDRVCURLState *s;
|
||||||
CURLState *state = NULL;
|
CURLState *state = NULL;
|
||||||
curl_easy_getinfo(curl, CURLINFO_PRIVATE, (char **)&state);
|
curl_easy_getinfo(curl, CURLINFO_PRIVATE, (char **)&state);
|
||||||
state->sock_fd = fd;
|
state->sock_fd = fd;
|
||||||
|
s = state->s;
|
||||||
|
|
||||||
DPRINTF("CURL (AIO): Sock action %d on fd %d\n", action, fd);
|
DPRINTF("CURL (AIO): Sock action %d on fd %d\n", action, fd);
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case CURL_POLL_IN:
|
case CURL_POLL_IN:
|
||||||
qemu_aio_set_fd_handler(fd, curl_multi_read, NULL, state);
|
aio_set_fd_handler(s->aio_context, fd, curl_multi_read,
|
||||||
|
NULL, state);
|
||||||
break;
|
break;
|
||||||
case CURL_POLL_OUT:
|
case CURL_POLL_OUT:
|
||||||
qemu_aio_set_fd_handler(fd, NULL, curl_multi_do, state);
|
aio_set_fd_handler(s->aio_context, fd, NULL, curl_multi_do, state);
|
||||||
break;
|
break;
|
||||||
case CURL_POLL_INOUT:
|
case CURL_POLL_INOUT:
|
||||||
qemu_aio_set_fd_handler(fd, curl_multi_read, curl_multi_do, state);
|
aio_set_fd_handler(s->aio_context, fd, curl_multi_read,
|
||||||
|
curl_multi_do, state);
|
||||||
break;
|
break;
|
||||||
case CURL_POLL_REMOVE:
|
case CURL_POLL_REMOVE:
|
||||||
qemu_aio_set_fd_handler(fd, NULL, NULL, NULL);
|
aio_set_fd_handler(s->aio_context, fd, NULL, NULL, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,7 +370,7 @@ static CURLState *curl_init_state(BDRVCURLState *s)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!state) {
|
if (!state) {
|
||||||
qemu_aio_wait();
|
aio_poll(state->s->aio_context, true);
|
||||||
}
|
}
|
||||||
} while(!state);
|
} while(!state);
|
||||||
|
|
||||||
@@ -422,6 +427,49 @@ static void curl_parse_filename(const char *filename, QDict *options,
|
|||||||
qdict_put(options, CURL_BLOCK_OPT_URL, qstring_from_str(filename));
|
qdict_put(options, CURL_BLOCK_OPT_URL, qstring_from_str(filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void curl_detach_aio_context(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
BDRVCURLState *s = bs->opaque;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < CURL_NUM_STATES; i++) {
|
||||||
|
if (s->states[i].in_use) {
|
||||||
|
curl_clean_state(&s->states[i]);
|
||||||
|
}
|
||||||
|
if (s->states[i].curl) {
|
||||||
|
curl_easy_cleanup(s->states[i].curl);
|
||||||
|
s->states[i].curl = NULL;
|
||||||
|
}
|
||||||
|
g_free(s->states[i].orig_buf);
|
||||||
|
s->states[i].orig_buf = NULL;
|
||||||
|
}
|
||||||
|
if (s->multi) {
|
||||||
|
curl_multi_cleanup(s->multi);
|
||||||
|
s->multi = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer_del(&s->timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void curl_attach_aio_context(BlockDriverState *bs,
|
||||||
|
AioContext *new_context)
|
||||||
|
{
|
||||||
|
BDRVCURLState *s = bs->opaque;
|
||||||
|
|
||||||
|
aio_timer_init(new_context, &s->timer,
|
||||||
|
QEMU_CLOCK_REALTIME, SCALE_NS,
|
||||||
|
curl_multi_timeout_do, s);
|
||||||
|
|
||||||
|
assert(!s->multi);
|
||||||
|
s->multi = curl_multi_init();
|
||||||
|
s->aio_context = new_context;
|
||||||
|
curl_multi_setopt(s->multi, CURLMOPT_SOCKETFUNCTION, curl_sock_cb);
|
||||||
|
#ifdef NEED_CURL_TIMER_CALLBACK
|
||||||
|
curl_multi_setopt(s->multi, CURLMOPT_TIMERDATA, s);
|
||||||
|
curl_multi_setopt(s->multi, CURLMOPT_TIMERFUNCTION, curl_timer_cb);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static QemuOptsList runtime_opts = {
|
static QemuOptsList runtime_opts = {
|
||||||
.name = "curl",
|
.name = "curl",
|
||||||
.head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
|
.head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
|
||||||
@@ -491,6 +539,7 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF("CURL: Opening %s\n", file);
|
DPRINTF("CURL: Opening %s\n", file);
|
||||||
|
s->aio_context = bdrv_get_aio_context(bs);
|
||||||
s->url = g_strdup(file);
|
s->url = g_strdup(file);
|
||||||
state = curl_init_state(s);
|
state = curl_init_state(s);
|
||||||
if (!state)
|
if (!state)
|
||||||
@@ -523,19 +572,7 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
|
|||||||
curl_easy_cleanup(state->curl);
|
curl_easy_cleanup(state->curl);
|
||||||
state->curl = NULL;
|
state->curl = NULL;
|
||||||
|
|
||||||
aio_timer_init(bdrv_get_aio_context(bs), &s->timer,
|
curl_attach_aio_context(bs, bdrv_get_aio_context(bs));
|
||||||
QEMU_CLOCK_REALTIME, SCALE_NS,
|
|
||||||
curl_multi_timeout_do, s);
|
|
||||||
|
|
||||||
// Now we know the file exists and its size, so let's
|
|
||||||
// initialize the multi interface!
|
|
||||||
|
|
||||||
s->multi = curl_multi_init();
|
|
||||||
curl_multi_setopt(s->multi, CURLMOPT_SOCKETFUNCTION, curl_sock_cb);
|
|
||||||
#ifdef NEED_CURL_TIMER_CALLBACK
|
|
||||||
curl_multi_setopt(s->multi, CURLMOPT_TIMERDATA, s);
|
|
||||||
curl_multi_setopt(s->multi, CURLMOPT_TIMERFUNCTION, curl_timer_cb);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
qemu_opts_del(opts);
|
qemu_opts_del(opts);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -599,8 +636,7 @@ static void curl_readv_bh_cb(void *p)
|
|||||||
acb->end = (acb->nb_sectors * SECTOR_SIZE);
|
acb->end = (acb->nb_sectors * SECTOR_SIZE);
|
||||||
|
|
||||||
state->buf_off = 0;
|
state->buf_off = 0;
|
||||||
if (state->orig_buf)
|
g_free(state->orig_buf);
|
||||||
g_free(state->orig_buf);
|
|
||||||
state->buf_start = start;
|
state->buf_start = start;
|
||||||
state->buf_len = acb->end + s->readahead_size;
|
state->buf_len = acb->end + s->readahead_size;
|
||||||
end = MIN(start + state->buf_len, s->len) - 1;
|
end = MIN(start + state->buf_len, s->len) - 1;
|
||||||
@@ -630,7 +666,7 @@ static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs,
|
|||||||
acb->sector_num = sector_num;
|
acb->sector_num = sector_num;
|
||||||
acb->nb_sectors = nb_sectors;
|
acb->nb_sectors = nb_sectors;
|
||||||
|
|
||||||
acb->bh = qemu_bh_new(curl_readv_bh_cb, acb);
|
acb->bh = aio_bh_new(bdrv_get_aio_context(bs), curl_readv_bh_cb, acb);
|
||||||
qemu_bh_schedule(acb->bh);
|
qemu_bh_schedule(acb->bh);
|
||||||
return &acb->common;
|
return &acb->common;
|
||||||
}
|
}
|
||||||
@@ -638,25 +674,9 @@ static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs,
|
|||||||
static void curl_close(BlockDriverState *bs)
|
static void curl_close(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVCURLState *s = bs->opaque;
|
BDRVCURLState *s = bs->opaque;
|
||||||
int i;
|
|
||||||
|
|
||||||
DPRINTF("CURL: Close\n");
|
DPRINTF("CURL: Close\n");
|
||||||
for (i=0; i<CURL_NUM_STATES; i++) {
|
curl_detach_aio_context(bs);
|
||||||
if (s->states[i].in_use)
|
|
||||||
curl_clean_state(&s->states[i]);
|
|
||||||
if (s->states[i].curl) {
|
|
||||||
curl_easy_cleanup(s->states[i].curl);
|
|
||||||
s->states[i].curl = NULL;
|
|
||||||
}
|
|
||||||
if (s->states[i].orig_buf) {
|
|
||||||
g_free(s->states[i].orig_buf);
|
|
||||||
s->states[i].orig_buf = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (s->multi)
|
|
||||||
curl_multi_cleanup(s->multi);
|
|
||||||
|
|
||||||
timer_del(&s->timer);
|
|
||||||
|
|
||||||
g_free(s->url);
|
g_free(s->url);
|
||||||
}
|
}
|
||||||
@@ -668,68 +688,83 @@ static int64_t curl_getlength(BlockDriverState *bs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static BlockDriver bdrv_http = {
|
static BlockDriver bdrv_http = {
|
||||||
.format_name = "http",
|
.format_name = "http",
|
||||||
.protocol_name = "http",
|
.protocol_name = "http",
|
||||||
|
|
||||||
.instance_size = sizeof(BDRVCURLState),
|
.instance_size = sizeof(BDRVCURLState),
|
||||||
.bdrv_parse_filename = curl_parse_filename,
|
.bdrv_parse_filename = curl_parse_filename,
|
||||||
.bdrv_file_open = curl_open,
|
.bdrv_file_open = curl_open,
|
||||||
.bdrv_close = curl_close,
|
.bdrv_close = curl_close,
|
||||||
.bdrv_getlength = curl_getlength,
|
.bdrv_getlength = curl_getlength,
|
||||||
|
|
||||||
.bdrv_aio_readv = curl_aio_readv,
|
.bdrv_aio_readv = curl_aio_readv,
|
||||||
|
|
||||||
|
.bdrv_detach_aio_context = curl_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = curl_attach_aio_context,
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_https = {
|
static BlockDriver bdrv_https = {
|
||||||
.format_name = "https",
|
.format_name = "https",
|
||||||
.protocol_name = "https",
|
.protocol_name = "https",
|
||||||
|
|
||||||
.instance_size = sizeof(BDRVCURLState),
|
.instance_size = sizeof(BDRVCURLState),
|
||||||
.bdrv_parse_filename = curl_parse_filename,
|
.bdrv_parse_filename = curl_parse_filename,
|
||||||
.bdrv_file_open = curl_open,
|
.bdrv_file_open = curl_open,
|
||||||
.bdrv_close = curl_close,
|
.bdrv_close = curl_close,
|
||||||
.bdrv_getlength = curl_getlength,
|
.bdrv_getlength = curl_getlength,
|
||||||
|
|
||||||
.bdrv_aio_readv = curl_aio_readv,
|
.bdrv_aio_readv = curl_aio_readv,
|
||||||
|
|
||||||
|
.bdrv_detach_aio_context = curl_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = curl_attach_aio_context,
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_ftp = {
|
static BlockDriver bdrv_ftp = {
|
||||||
.format_name = "ftp",
|
.format_name = "ftp",
|
||||||
.protocol_name = "ftp",
|
.protocol_name = "ftp",
|
||||||
|
|
||||||
.instance_size = sizeof(BDRVCURLState),
|
.instance_size = sizeof(BDRVCURLState),
|
||||||
.bdrv_parse_filename = curl_parse_filename,
|
.bdrv_parse_filename = curl_parse_filename,
|
||||||
.bdrv_file_open = curl_open,
|
.bdrv_file_open = curl_open,
|
||||||
.bdrv_close = curl_close,
|
.bdrv_close = curl_close,
|
||||||
.bdrv_getlength = curl_getlength,
|
.bdrv_getlength = curl_getlength,
|
||||||
|
|
||||||
.bdrv_aio_readv = curl_aio_readv,
|
.bdrv_aio_readv = curl_aio_readv,
|
||||||
|
|
||||||
|
.bdrv_detach_aio_context = curl_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = curl_attach_aio_context,
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_ftps = {
|
static BlockDriver bdrv_ftps = {
|
||||||
.format_name = "ftps",
|
.format_name = "ftps",
|
||||||
.protocol_name = "ftps",
|
.protocol_name = "ftps",
|
||||||
|
|
||||||
.instance_size = sizeof(BDRVCURLState),
|
.instance_size = sizeof(BDRVCURLState),
|
||||||
.bdrv_parse_filename = curl_parse_filename,
|
.bdrv_parse_filename = curl_parse_filename,
|
||||||
.bdrv_file_open = curl_open,
|
.bdrv_file_open = curl_open,
|
||||||
.bdrv_close = curl_close,
|
.bdrv_close = curl_close,
|
||||||
.bdrv_getlength = curl_getlength,
|
.bdrv_getlength = curl_getlength,
|
||||||
|
|
||||||
.bdrv_aio_readv = curl_aio_readv,
|
.bdrv_aio_readv = curl_aio_readv,
|
||||||
|
|
||||||
|
.bdrv_detach_aio_context = curl_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = curl_attach_aio_context,
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_tftp = {
|
static BlockDriver bdrv_tftp = {
|
||||||
.format_name = "tftp",
|
.format_name = "tftp",
|
||||||
.protocol_name = "tftp",
|
.protocol_name = "tftp",
|
||||||
|
|
||||||
.instance_size = sizeof(BDRVCURLState),
|
.instance_size = sizeof(BDRVCURLState),
|
||||||
.bdrv_parse_filename = curl_parse_filename,
|
.bdrv_parse_filename = curl_parse_filename,
|
||||||
.bdrv_file_open = curl_open,
|
.bdrv_file_open = curl_open,
|
||||||
.bdrv_close = curl_close,
|
.bdrv_close = curl_close,
|
||||||
.bdrv_getlength = curl_getlength,
|
.bdrv_getlength = curl_getlength,
|
||||||
|
|
||||||
.bdrv_aio_readv = curl_aio_readv,
|
.bdrv_aio_readv = curl_aio_readv,
|
||||||
|
|
||||||
|
.bdrv_detach_aio_context = curl_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = curl_attach_aio_context,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void curl_block_init(void)
|
static void curl_block_init(void)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ typedef struct GlusterAIOCB {
|
|||||||
int ret;
|
int ret;
|
||||||
QEMUBH *bh;
|
QEMUBH *bh;
|
||||||
Coroutine *coroutine;
|
Coroutine *coroutine;
|
||||||
|
AioContext *aio_context;
|
||||||
} GlusterAIOCB;
|
} GlusterAIOCB;
|
||||||
|
|
||||||
typedef struct BDRVGlusterState {
|
typedef struct BDRVGlusterState {
|
||||||
@@ -249,7 +250,7 @@ static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret, void *arg)
|
|||||||
acb->ret = -EIO; /* Partial read/write - fail it */
|
acb->ret = -EIO; /* Partial read/write - fail it */
|
||||||
}
|
}
|
||||||
|
|
||||||
acb->bh = qemu_bh_new(qemu_gluster_complete_aio, acb);
|
acb->bh = aio_bh_new(acb->aio_context, qemu_gluster_complete_aio, acb);
|
||||||
qemu_bh_schedule(acb->bh);
|
qemu_bh_schedule(acb->bh);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -436,6 +437,7 @@ static coroutine_fn int qemu_gluster_co_write_zeroes(BlockDriverState *bs,
|
|||||||
acb->size = size;
|
acb->size = size;
|
||||||
acb->ret = 0;
|
acb->ret = 0;
|
||||||
acb->coroutine = qemu_coroutine_self();
|
acb->coroutine = qemu_coroutine_self();
|
||||||
|
acb->aio_context = bdrv_get_aio_context(bs);
|
||||||
|
|
||||||
ret = glfs_zerofill_async(s->fd, offset, size, &gluster_finish_aiocb, acb);
|
ret = glfs_zerofill_async(s->fd, offset, size, &gluster_finish_aiocb, acb);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -476,13 +478,14 @@ static inline int qemu_gluster_zerofill(struct glfs_fd *fd, int64_t offset,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int qemu_gluster_create(const char *filename,
|
static int qemu_gluster_create(const char *filename,
|
||||||
QEMUOptionParameter *options, Error **errp)
|
QemuOpts *opts, Error **errp)
|
||||||
{
|
{
|
||||||
struct glfs *glfs;
|
struct glfs *glfs;
|
||||||
struct glfs_fd *fd;
|
struct glfs_fd *fd;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int prealloc = 0;
|
int prealloc = 0;
|
||||||
int64_t total_size = 0;
|
int64_t total_size = 0;
|
||||||
|
char *tmp = NULL;
|
||||||
GlusterConf *gconf = g_malloc0(sizeof(GlusterConf));
|
GlusterConf *gconf = g_malloc0(sizeof(GlusterConf));
|
||||||
|
|
||||||
glfs = qemu_gluster_init(gconf, filename, errp);
|
glfs = qemu_gluster_init(gconf, filename, errp);
|
||||||
@@ -491,24 +494,21 @@ static int qemu_gluster_create(const char *filename,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (options && options->name) {
|
total_size =
|
||||||
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
|
qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
|
||||||
total_size = options->value.n / BDRV_SECTOR_SIZE;
|
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
|
tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
|
||||||
if (!options->value.s || !strcmp(options->value.s, "off")) {
|
if (!tmp || !strcmp(tmp, "off")) {
|
||||||
prealloc = 0;
|
prealloc = 0;
|
||||||
} else if (!strcmp(options->value.s, "full") &&
|
} else if (!strcmp(tmp, "full") &&
|
||||||
gluster_supports_zerofill()) {
|
gluster_supports_zerofill()) {
|
||||||
prealloc = 1;
|
prealloc = 1;
|
||||||
} else {
|
} else {
|
||||||
error_setg(errp, "Invalid preallocation mode: '%s'"
|
error_setg(errp, "Invalid preallocation mode: '%s'"
|
||||||
" or GlusterFS doesn't support zerofill API",
|
" or GlusterFS doesn't support zerofill API",
|
||||||
options->value.s);
|
tmp);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
}
|
|
||||||
options++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = glfs_creat(glfs, gconf->image,
|
fd = glfs_creat(glfs, gconf->image,
|
||||||
@@ -530,6 +530,7 @@ static int qemu_gluster_create(const char *filename,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
g_free(tmp);
|
||||||
qemu_gluster_gconf_free(gconf);
|
qemu_gluster_gconf_free(gconf);
|
||||||
if (glfs) {
|
if (glfs) {
|
||||||
glfs_fini(glfs);
|
glfs_fini(glfs);
|
||||||
@@ -549,6 +550,7 @@ static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs,
|
|||||||
acb->size = size;
|
acb->size = size;
|
||||||
acb->ret = 0;
|
acb->ret = 0;
|
||||||
acb->coroutine = qemu_coroutine_self();
|
acb->coroutine = qemu_coroutine_self();
|
||||||
|
acb->aio_context = bdrv_get_aio_context(bs);
|
||||||
|
|
||||||
if (write) {
|
if (write) {
|
||||||
ret = glfs_pwritev_async(s->fd, qiov->iov, qiov->niov, offset, 0,
|
ret = glfs_pwritev_async(s->fd, qiov->iov, qiov->niov, offset, 0,
|
||||||
@@ -605,6 +607,7 @@ static coroutine_fn int qemu_gluster_co_flush_to_disk(BlockDriverState *bs)
|
|||||||
acb->size = 0;
|
acb->size = 0;
|
||||||
acb->ret = 0;
|
acb->ret = 0;
|
||||||
acb->coroutine = qemu_coroutine_self();
|
acb->coroutine = qemu_coroutine_self();
|
||||||
|
acb->aio_context = bdrv_get_aio_context(bs);
|
||||||
|
|
||||||
ret = glfs_fsync_async(s->fd, &gluster_finish_aiocb, acb);
|
ret = glfs_fsync_async(s->fd, &gluster_finish_aiocb, acb);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -633,6 +636,7 @@ static coroutine_fn int qemu_gluster_co_discard(BlockDriverState *bs,
|
|||||||
acb->size = 0;
|
acb->size = 0;
|
||||||
acb->ret = 0;
|
acb->ret = 0;
|
||||||
acb->coroutine = qemu_coroutine_self();
|
acb->coroutine = qemu_coroutine_self();
|
||||||
|
acb->aio_context = bdrv_get_aio_context(bs);
|
||||||
|
|
||||||
ret = glfs_discard_async(s->fd, offset, size, &gluster_finish_aiocb, acb);
|
ret = glfs_discard_async(s->fd, offset, size, &gluster_finish_aiocb, acb);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -693,18 +697,22 @@ static int qemu_gluster_has_zero_init(BlockDriverState *bs)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QEMUOptionParameter qemu_gluster_create_options[] = {
|
static QemuOptsList qemu_gluster_create_opts = {
|
||||||
{
|
.name = "qemu-gluster-create-opts",
|
||||||
.name = BLOCK_OPT_SIZE,
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_gluster_create_opts.head),
|
||||||
.type = OPT_SIZE,
|
.desc = {
|
||||||
.help = "Virtual disk size"
|
{
|
||||||
},
|
.name = BLOCK_OPT_SIZE,
|
||||||
{
|
.type = QEMU_OPT_SIZE,
|
||||||
.name = BLOCK_OPT_PREALLOC,
|
.help = "Virtual disk size"
|
||||||
.type = OPT_STRING,
|
},
|
||||||
.help = "Preallocation mode (allowed values: off, full)"
|
{
|
||||||
},
|
.name = BLOCK_OPT_PREALLOC,
|
||||||
{ NULL }
|
.type = QEMU_OPT_STRING,
|
||||||
|
.help = "Preallocation mode (allowed values: off, full)"
|
||||||
|
},
|
||||||
|
{ /* end of list */ }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_gluster = {
|
static BlockDriver bdrv_gluster = {
|
||||||
@@ -731,7 +739,7 @@ static BlockDriver bdrv_gluster = {
|
|||||||
#ifdef CONFIG_GLUSTERFS_ZEROFILL
|
#ifdef CONFIG_GLUSTERFS_ZEROFILL
|
||||||
.bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
|
.bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
|
||||||
#endif
|
#endif
|
||||||
.create_options = qemu_gluster_create_options,
|
.create_opts = &qemu_gluster_create_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_gluster_tcp = {
|
static BlockDriver bdrv_gluster_tcp = {
|
||||||
@@ -758,7 +766,7 @@ static BlockDriver bdrv_gluster_tcp = {
|
|||||||
#ifdef CONFIG_GLUSTERFS_ZEROFILL
|
#ifdef CONFIG_GLUSTERFS_ZEROFILL
|
||||||
.bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
|
.bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
|
||||||
#endif
|
#endif
|
||||||
.create_options = qemu_gluster_create_options,
|
.create_opts = &qemu_gluster_create_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_gluster_unix = {
|
static BlockDriver bdrv_gluster_unix = {
|
||||||
@@ -785,7 +793,7 @@ static BlockDriver bdrv_gluster_unix = {
|
|||||||
#ifdef CONFIG_GLUSTERFS_ZEROFILL
|
#ifdef CONFIG_GLUSTERFS_ZEROFILL
|
||||||
.bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
|
.bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
|
||||||
#endif
|
#endif
|
||||||
.create_options = qemu_gluster_create_options,
|
.create_opts = &qemu_gluster_create_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_gluster_rdma = {
|
static BlockDriver bdrv_gluster_rdma = {
|
||||||
@@ -812,7 +820,7 @@ static BlockDriver bdrv_gluster_rdma = {
|
|||||||
#ifdef CONFIG_GLUSTERFS_ZEROFILL
|
#ifdef CONFIG_GLUSTERFS_ZEROFILL
|
||||||
.bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
|
.bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
|
||||||
#endif
|
#endif
|
||||||
.create_options = qemu_gluster_create_options,
|
.create_opts = &qemu_gluster_create_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void bdrv_gluster_init(void)
|
static void bdrv_gluster_init(void)
|
||||||
|
|||||||
116
block/iscsi.c
116
block/iscsi.c
@@ -49,6 +49,7 @@
|
|||||||
|
|
||||||
typedef struct IscsiLun {
|
typedef struct IscsiLun {
|
||||||
struct iscsi_context *iscsi;
|
struct iscsi_context *iscsi;
|
||||||
|
AioContext *aio_context;
|
||||||
int lun;
|
int lun;
|
||||||
enum scsi_inquiry_peripheral_device_type type;
|
enum scsi_inquiry_peripheral_device_type type;
|
||||||
int block_size;
|
int block_size;
|
||||||
@@ -73,6 +74,7 @@ typedef struct IscsiTask {
|
|||||||
struct scsi_task *task;
|
struct scsi_task *task;
|
||||||
Coroutine *co;
|
Coroutine *co;
|
||||||
QEMUBH *bh;
|
QEMUBH *bh;
|
||||||
|
IscsiLun *iscsilun;
|
||||||
} IscsiTask;
|
} IscsiTask;
|
||||||
|
|
||||||
typedef struct IscsiAIOCB {
|
typedef struct IscsiAIOCB {
|
||||||
@@ -133,7 +135,7 @@ iscsi_schedule_bh(IscsiAIOCB *acb)
|
|||||||
if (acb->bh) {
|
if (acb->bh) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
acb->bh = qemu_bh_new(iscsi_bh_cb, acb);
|
acb->bh = aio_bh_new(acb->iscsilun->aio_context, iscsi_bh_cb, acb);
|
||||||
qemu_bh_schedule(acb->bh);
|
qemu_bh_schedule(acb->bh);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +171,8 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
if (iTask->co) {
|
if (iTask->co) {
|
||||||
iTask->bh = qemu_bh_new(iscsi_co_generic_bh_cb, iTask);
|
iTask->bh = aio_bh_new(iTask->iscsilun->aio_context,
|
||||||
|
iscsi_co_generic_bh_cb, iTask);
|
||||||
qemu_bh_schedule(iTask->bh);
|
qemu_bh_schedule(iTask->bh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,8 +180,9 @@ out:
|
|||||||
static void iscsi_co_init_iscsitask(IscsiLun *iscsilun, struct IscsiTask *iTask)
|
static void iscsi_co_init_iscsitask(IscsiLun *iscsilun, struct IscsiTask *iTask)
|
||||||
{
|
{
|
||||||
*iTask = (struct IscsiTask) {
|
*iTask = (struct IscsiTask) {
|
||||||
.co = qemu_coroutine_self(),
|
.co = qemu_coroutine_self(),
|
||||||
.retries = ISCSI_CMD_RETRIES,
|
.retries = ISCSI_CMD_RETRIES,
|
||||||
|
.iscsilun = iscsilun,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +213,7 @@ iscsi_aio_cancel(BlockDriverAIOCB *blockacb)
|
|||||||
iscsi_abort_task_cb, acb);
|
iscsi_abort_task_cb, acb);
|
||||||
|
|
||||||
while (acb->status == -EINPROGRESS) {
|
while (acb->status == -EINPROGRESS) {
|
||||||
qemu_aio_wait();
|
aio_poll(iscsilun->aio_context, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,10 +236,11 @@ iscsi_set_events(IscsiLun *iscsilun)
|
|||||||
ev = POLLIN;
|
ev = POLLIN;
|
||||||
ev |= iscsi_which_events(iscsi);
|
ev |= iscsi_which_events(iscsi);
|
||||||
if (ev != iscsilun->events) {
|
if (ev != iscsilun->events) {
|
||||||
qemu_aio_set_fd_handler(iscsi_get_fd(iscsi),
|
aio_set_fd_handler(iscsilun->aio_context,
|
||||||
iscsi_process_read,
|
iscsi_get_fd(iscsi),
|
||||||
(ev & POLLOUT) ? iscsi_process_write : NULL,
|
iscsi_process_read,
|
||||||
iscsilun);
|
(ev & POLLOUT) ? iscsi_process_write : NULL,
|
||||||
|
iscsilun);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -791,7 +796,7 @@ static int iscsi_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
|
|||||||
iscsi_aio_ioctl(bs, req, buf, ioctl_cb, &status);
|
iscsi_aio_ioctl(bs, req, buf, ioctl_cb, &status);
|
||||||
|
|
||||||
while (status == -EINPROGRESS) {
|
while (status == -EINPROGRESS) {
|
||||||
qemu_aio_wait();
|
aio_poll(iscsilun->aio_context, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1195,6 +1200,40 @@ fail_with_err:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void iscsi_detach_aio_context(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
IscsiLun *iscsilun = bs->opaque;
|
||||||
|
|
||||||
|
aio_set_fd_handler(iscsilun->aio_context,
|
||||||
|
iscsi_get_fd(iscsilun->iscsi),
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
iscsilun->events = 0;
|
||||||
|
|
||||||
|
if (iscsilun->nop_timer) {
|
||||||
|
timer_del(iscsilun->nop_timer);
|
||||||
|
timer_free(iscsilun->nop_timer);
|
||||||
|
iscsilun->nop_timer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void iscsi_attach_aio_context(BlockDriverState *bs,
|
||||||
|
AioContext *new_context)
|
||||||
|
{
|
||||||
|
IscsiLun *iscsilun = bs->opaque;
|
||||||
|
|
||||||
|
iscsilun->aio_context = new_context;
|
||||||
|
iscsi_set_events(iscsilun);
|
||||||
|
|
||||||
|
#if defined(LIBISCSI_FEATURE_NOP_COUNTER)
|
||||||
|
/* Set up a timer for sending out iSCSI NOPs */
|
||||||
|
iscsilun->nop_timer = aio_timer_new(iscsilun->aio_context,
|
||||||
|
QEMU_CLOCK_REALTIME, SCALE_MS,
|
||||||
|
iscsi_nop_timed_event, iscsilun);
|
||||||
|
timer_mod(iscsilun->nop_timer,
|
||||||
|
qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + NOP_INTERVAL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We support iscsi url's on the form
|
* We support iscsi url's on the form
|
||||||
* iscsi://[<username>%<password>@]<host>[:<port>]/<targetname>/<lun>
|
* iscsi://[<username>%<password>@]<host>[:<port>]/<targetname>/<lun>
|
||||||
@@ -1301,6 +1340,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
|
|||||||
}
|
}
|
||||||
|
|
||||||
iscsilun->iscsi = iscsi;
|
iscsilun->iscsi = iscsi;
|
||||||
|
iscsilun->aio_context = bdrv_get_aio_context(bs);
|
||||||
iscsilun->lun = iscsi_url->lun;
|
iscsilun->lun = iscsi_url->lun;
|
||||||
iscsilun->has_write_same = true;
|
iscsilun->has_write_same = true;
|
||||||
|
|
||||||
@@ -1374,11 +1414,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
|
|||||||
scsi_free_scsi_task(task);
|
scsi_free_scsi_task(task);
|
||||||
task = NULL;
|
task = NULL;
|
||||||
|
|
||||||
#if defined(LIBISCSI_FEATURE_NOP_COUNTER)
|
iscsi_attach_aio_context(bs, iscsilun->aio_context);
|
||||||
/* Set up a timer for sending out iSCSI NOPs */
|
|
||||||
iscsilun->nop_timer = timer_new_ms(QEMU_CLOCK_REALTIME, iscsi_nop_timed_event, iscsilun);
|
|
||||||
timer_mod(iscsilun->nop_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + NOP_INTERVAL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Guess the internal cluster (page) size of the iscsi target by the means
|
/* Guess the internal cluster (page) size of the iscsi target by the means
|
||||||
* of opt_unmap_gran. Transfer the unmap granularity only if it has a
|
* of opt_unmap_gran. Transfer the unmap granularity only if it has a
|
||||||
@@ -1398,9 +1434,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
qemu_opts_del(opts);
|
qemu_opts_del(opts);
|
||||||
if (initiator_name != NULL) {
|
g_free(initiator_name);
|
||||||
g_free(initiator_name);
|
|
||||||
}
|
|
||||||
if (iscsi_url != NULL) {
|
if (iscsi_url != NULL) {
|
||||||
iscsi_destroy_url(iscsi_url);
|
iscsi_destroy_url(iscsi_url);
|
||||||
}
|
}
|
||||||
@@ -1422,11 +1456,7 @@ static void iscsi_close(BlockDriverState *bs)
|
|||||||
IscsiLun *iscsilun = bs->opaque;
|
IscsiLun *iscsilun = bs->opaque;
|
||||||
struct iscsi_context *iscsi = iscsilun->iscsi;
|
struct iscsi_context *iscsi = iscsilun->iscsi;
|
||||||
|
|
||||||
if (iscsilun->nop_timer) {
|
iscsi_detach_aio_context(bs);
|
||||||
timer_del(iscsilun->nop_timer);
|
|
||||||
timer_free(iscsilun->nop_timer);
|
|
||||||
}
|
|
||||||
qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), NULL, NULL, NULL);
|
|
||||||
iscsi_destroy_context(iscsi);
|
iscsi_destroy_context(iscsi);
|
||||||
g_free(iscsilun->zeroblock);
|
g_free(iscsilun->zeroblock);
|
||||||
g_free(iscsilun->allocationmap);
|
g_free(iscsilun->allocationmap);
|
||||||
@@ -1500,8 +1530,7 @@ static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iscsi_create(const char *filename, QEMUOptionParameter *options,
|
static int iscsi_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int64_t total_size = 0;
|
int64_t total_size = 0;
|
||||||
@@ -1512,13 +1541,8 @@ static int iscsi_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
bs = bdrv_new("", &error_abort);
|
bs = bdrv_new("", &error_abort);
|
||||||
|
|
||||||
/* Read out options */
|
/* Read out options */
|
||||||
while (options && options->name) {
|
total_size =
|
||||||
if (!strcmp(options->name, "size")) {
|
qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
|
||||||
total_size = options->value.n / BDRV_SECTOR_SIZE;
|
|
||||||
}
|
|
||||||
options++;
|
|
||||||
}
|
|
||||||
|
|
||||||
bs->opaque = g_malloc0(sizeof(struct IscsiLun));
|
bs->opaque = g_malloc0(sizeof(struct IscsiLun));
|
||||||
iscsilun = bs->opaque;
|
iscsilun = bs->opaque;
|
||||||
|
|
||||||
@@ -1530,10 +1554,7 @@ static int iscsi_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (iscsilun->nop_timer) {
|
iscsi_detach_aio_context(bs);
|
||||||
timer_del(iscsilun->nop_timer);
|
|
||||||
timer_free(iscsilun->nop_timer);
|
|
||||||
}
|
|
||||||
if (iscsilun->type != TYPE_DISK) {
|
if (iscsilun->type != TYPE_DISK) {
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -1563,13 +1584,17 @@ static int iscsi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QEMUOptionParameter iscsi_create_options[] = {
|
static QemuOptsList iscsi_create_opts = {
|
||||||
{
|
.name = "iscsi-create-opts",
|
||||||
.name = BLOCK_OPT_SIZE,
|
.head = QTAILQ_HEAD_INITIALIZER(iscsi_create_opts.head),
|
||||||
.type = OPT_SIZE,
|
.desc = {
|
||||||
.help = "Virtual disk size"
|
{
|
||||||
},
|
.name = BLOCK_OPT_SIZE,
|
||||||
{ NULL }
|
.type = QEMU_OPT_SIZE,
|
||||||
|
.help = "Virtual disk size"
|
||||||
|
},
|
||||||
|
{ /* end of list */ }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_iscsi = {
|
static BlockDriver bdrv_iscsi = {
|
||||||
@@ -1581,7 +1606,7 @@ static BlockDriver bdrv_iscsi = {
|
|||||||
.bdrv_file_open = iscsi_open,
|
.bdrv_file_open = iscsi_open,
|
||||||
.bdrv_close = iscsi_close,
|
.bdrv_close = iscsi_close,
|
||||||
.bdrv_create = iscsi_create,
|
.bdrv_create = iscsi_create,
|
||||||
.create_options = iscsi_create_options,
|
.create_opts = &iscsi_create_opts,
|
||||||
.bdrv_reopen_prepare = iscsi_reopen_prepare,
|
.bdrv_reopen_prepare = iscsi_reopen_prepare,
|
||||||
|
|
||||||
.bdrv_getlength = iscsi_getlength,
|
.bdrv_getlength = iscsi_getlength,
|
||||||
@@ -1604,6 +1629,9 @@ static BlockDriver bdrv_iscsi = {
|
|||||||
.bdrv_ioctl = iscsi_ioctl,
|
.bdrv_ioctl = iscsi_ioctl,
|
||||||
.bdrv_aio_ioctl = iscsi_aio_ioctl,
|
.bdrv_aio_ioctl = iscsi_aio_ioctl,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
.bdrv_detach_aio_context = iscsi_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = iscsi_attach_aio_context,
|
||||||
};
|
};
|
||||||
|
|
||||||
static QemuOptsList qemu_iscsi_opts = {
|
static QemuOptsList qemu_iscsi_opts = {
|
||||||
|
|||||||
@@ -177,6 +177,20 @@ out_free_aiocb:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void laio_detach_aio_context(void *s_, AioContext *old_context)
|
||||||
|
{
|
||||||
|
struct qemu_laio_state *s = s_;
|
||||||
|
|
||||||
|
aio_set_event_notifier(old_context, &s->e, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void laio_attach_aio_context(void *s_, AioContext *new_context)
|
||||||
|
{
|
||||||
|
struct qemu_laio_state *s = s_;
|
||||||
|
|
||||||
|
aio_set_event_notifier(new_context, &s->e, qemu_laio_completion_cb);
|
||||||
|
}
|
||||||
|
|
||||||
void *laio_init(void)
|
void *laio_init(void)
|
||||||
{
|
{
|
||||||
struct qemu_laio_state *s;
|
struct qemu_laio_state *s;
|
||||||
@@ -190,8 +204,6 @@ void *laio_init(void)
|
|||||||
goto out_close_efd;
|
goto out_close_efd;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_aio_set_event_notifier(&s->e, qemu_laio_completion_cb);
|
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
|
||||||
out_close_efd:
|
out_close_efd:
|
||||||
@@ -200,3 +212,11 @@ out_free_state:
|
|||||||
g_free(s);
|
g_free(s);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void laio_cleanup(void *s_)
|
||||||
|
{
|
||||||
|
struct qemu_laio_state *s = s_;
|
||||||
|
|
||||||
|
event_notifier_cleanup(&s->e);
|
||||||
|
g_free(s);
|
||||||
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ static void nbd_teardown_connection(NbdClientSession *client)
|
|||||||
shutdown(client->sock, 2);
|
shutdown(client->sock, 2);
|
||||||
nbd_recv_coroutines_enter_all(client);
|
nbd_recv_coroutines_enter_all(client);
|
||||||
|
|
||||||
qemu_aio_set_fd_handler(client->sock, NULL, NULL, NULL);
|
nbd_client_session_detach_aio_context(client);
|
||||||
closesocket(client->sock);
|
closesocket(client->sock);
|
||||||
client->sock = -1;
|
client->sock = -1;
|
||||||
}
|
}
|
||||||
@@ -103,11 +103,14 @@ static int nbd_co_send_request(NbdClientSession *s,
|
|||||||
struct nbd_request *request,
|
struct nbd_request *request,
|
||||||
QEMUIOVector *qiov, int offset)
|
QEMUIOVector *qiov, int offset)
|
||||||
{
|
{
|
||||||
|
AioContext *aio_context;
|
||||||
int rc, ret;
|
int rc, ret;
|
||||||
|
|
||||||
qemu_co_mutex_lock(&s->send_mutex);
|
qemu_co_mutex_lock(&s->send_mutex);
|
||||||
s->send_coroutine = qemu_coroutine_self();
|
s->send_coroutine = qemu_coroutine_self();
|
||||||
qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, nbd_restart_write, s);
|
aio_context = bdrv_get_aio_context(s->bs);
|
||||||
|
aio_set_fd_handler(aio_context, s->sock,
|
||||||
|
nbd_reply_ready, nbd_restart_write, s);
|
||||||
if (qiov) {
|
if (qiov) {
|
||||||
if (!s->is_unix) {
|
if (!s->is_unix) {
|
||||||
socket_set_cork(s->sock, 1);
|
socket_set_cork(s->sock, 1);
|
||||||
@@ -126,7 +129,7 @@ static int nbd_co_send_request(NbdClientSession *s,
|
|||||||
} else {
|
} else {
|
||||||
rc = nbd_send_request(s->sock, request);
|
rc = nbd_send_request(s->sock, request);
|
||||||
}
|
}
|
||||||
qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, NULL, s);
|
aio_set_fd_handler(aio_context, s->sock, nbd_reply_ready, NULL, s);
|
||||||
s->send_coroutine = NULL;
|
s->send_coroutine = NULL;
|
||||||
qemu_co_mutex_unlock(&s->send_mutex);
|
qemu_co_mutex_unlock(&s->send_mutex);
|
||||||
return rc;
|
return rc;
|
||||||
@@ -335,6 +338,19 @@ int nbd_client_session_co_discard(NbdClientSession *client, int64_t sector_num,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nbd_client_session_detach_aio_context(NbdClientSession *client)
|
||||||
|
{
|
||||||
|
aio_set_fd_handler(bdrv_get_aio_context(client->bs), client->sock,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nbd_client_session_attach_aio_context(NbdClientSession *client,
|
||||||
|
AioContext *new_context)
|
||||||
|
{
|
||||||
|
aio_set_fd_handler(new_context, client->sock,
|
||||||
|
nbd_reply_ready, NULL, client);
|
||||||
|
}
|
||||||
|
|
||||||
void nbd_client_session_close(NbdClientSession *client)
|
void nbd_client_session_close(NbdClientSession *client)
|
||||||
{
|
{
|
||||||
struct nbd_request request = {
|
struct nbd_request request = {
|
||||||
@@ -381,7 +397,7 @@ int nbd_client_session_init(NbdClientSession *client, BlockDriverState *bs,
|
|||||||
/* Now that we're connected, set the socket to be non-blocking and
|
/* Now that we're connected, set the socket to be non-blocking and
|
||||||
* kick the reply mechanism. */
|
* kick the reply mechanism. */
|
||||||
qemu_set_nonblock(sock);
|
qemu_set_nonblock(sock);
|
||||||
qemu_aio_set_fd_handler(sock, nbd_reply_ready, NULL, client);
|
nbd_client_session_attach_aio_context(client, bdrv_get_aio_context(bs));
|
||||||
|
|
||||||
logout("Established connection with NBD server\n");
|
logout("Established connection with NBD server\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -47,4 +47,8 @@ int nbd_client_session_co_writev(NbdClientSession *client, int64_t sector_num,
|
|||||||
int nbd_client_session_co_readv(NbdClientSession *client, int64_t sector_num,
|
int nbd_client_session_co_readv(NbdClientSession *client, int64_t sector_num,
|
||||||
int nb_sectors, QEMUIOVector *qiov);
|
int nb_sectors, QEMUIOVector *qiov);
|
||||||
|
|
||||||
|
void nbd_client_session_detach_aio_context(NbdClientSession *client);
|
||||||
|
void nbd_client_session_attach_aio_context(NbdClientSession *client,
|
||||||
|
AioContext *new_context);
|
||||||
|
|
||||||
#endif /* NBD_CLIENT_H */
|
#endif /* NBD_CLIENT_H */
|
||||||
|
|||||||
87
block/nbd.c
87
block/nbd.c
@@ -323,46 +323,67 @@ static int64_t nbd_getlength(BlockDriverState *bs)
|
|||||||
return s->client.size;
|
return s->client.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void nbd_detach_aio_context(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
BDRVNBDState *s = bs->opaque;
|
||||||
|
|
||||||
|
nbd_client_session_detach_aio_context(&s->client);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nbd_attach_aio_context(BlockDriverState *bs,
|
||||||
|
AioContext *new_context)
|
||||||
|
{
|
||||||
|
BDRVNBDState *s = bs->opaque;
|
||||||
|
|
||||||
|
nbd_client_session_attach_aio_context(&s->client, new_context);
|
||||||
|
}
|
||||||
|
|
||||||
static BlockDriver bdrv_nbd = {
|
static BlockDriver bdrv_nbd = {
|
||||||
.format_name = "nbd",
|
.format_name = "nbd",
|
||||||
.protocol_name = "nbd",
|
.protocol_name = "nbd",
|
||||||
.instance_size = sizeof(BDRVNBDState),
|
.instance_size = sizeof(BDRVNBDState),
|
||||||
.bdrv_parse_filename = nbd_parse_filename,
|
.bdrv_parse_filename = nbd_parse_filename,
|
||||||
.bdrv_file_open = nbd_open,
|
.bdrv_file_open = nbd_open,
|
||||||
.bdrv_co_readv = nbd_co_readv,
|
.bdrv_co_readv = nbd_co_readv,
|
||||||
.bdrv_co_writev = nbd_co_writev,
|
.bdrv_co_writev = nbd_co_writev,
|
||||||
.bdrv_close = nbd_close,
|
.bdrv_close = nbd_close,
|
||||||
.bdrv_co_flush_to_os = nbd_co_flush,
|
.bdrv_co_flush_to_os = nbd_co_flush,
|
||||||
.bdrv_co_discard = nbd_co_discard,
|
.bdrv_co_discard = nbd_co_discard,
|
||||||
.bdrv_getlength = nbd_getlength,
|
.bdrv_getlength = nbd_getlength,
|
||||||
|
.bdrv_detach_aio_context = nbd_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = nbd_attach_aio_context,
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_nbd_tcp = {
|
static BlockDriver bdrv_nbd_tcp = {
|
||||||
.format_name = "nbd",
|
.format_name = "nbd",
|
||||||
.protocol_name = "nbd+tcp",
|
.protocol_name = "nbd+tcp",
|
||||||
.instance_size = sizeof(BDRVNBDState),
|
.instance_size = sizeof(BDRVNBDState),
|
||||||
.bdrv_parse_filename = nbd_parse_filename,
|
.bdrv_parse_filename = nbd_parse_filename,
|
||||||
.bdrv_file_open = nbd_open,
|
.bdrv_file_open = nbd_open,
|
||||||
.bdrv_co_readv = nbd_co_readv,
|
.bdrv_co_readv = nbd_co_readv,
|
||||||
.bdrv_co_writev = nbd_co_writev,
|
.bdrv_co_writev = nbd_co_writev,
|
||||||
.bdrv_close = nbd_close,
|
.bdrv_close = nbd_close,
|
||||||
.bdrv_co_flush_to_os = nbd_co_flush,
|
.bdrv_co_flush_to_os = nbd_co_flush,
|
||||||
.bdrv_co_discard = nbd_co_discard,
|
.bdrv_co_discard = nbd_co_discard,
|
||||||
.bdrv_getlength = nbd_getlength,
|
.bdrv_getlength = nbd_getlength,
|
||||||
|
.bdrv_detach_aio_context = nbd_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = nbd_attach_aio_context,
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_nbd_unix = {
|
static BlockDriver bdrv_nbd_unix = {
|
||||||
.format_name = "nbd",
|
.format_name = "nbd",
|
||||||
.protocol_name = "nbd+unix",
|
.protocol_name = "nbd+unix",
|
||||||
.instance_size = sizeof(BDRVNBDState),
|
.instance_size = sizeof(BDRVNBDState),
|
||||||
.bdrv_parse_filename = nbd_parse_filename,
|
.bdrv_parse_filename = nbd_parse_filename,
|
||||||
.bdrv_file_open = nbd_open,
|
.bdrv_file_open = nbd_open,
|
||||||
.bdrv_co_readv = nbd_co_readv,
|
.bdrv_co_readv = nbd_co_readv,
|
||||||
.bdrv_co_writev = nbd_co_writev,
|
.bdrv_co_writev = nbd_co_writev,
|
||||||
.bdrv_close = nbd_close,
|
.bdrv_close = nbd_close,
|
||||||
.bdrv_co_flush_to_os = nbd_co_flush,
|
.bdrv_co_flush_to_os = nbd_co_flush,
|
||||||
.bdrv_co_discard = nbd_co_discard,
|
.bdrv_co_discard = nbd_co_discard,
|
||||||
.bdrv_getlength = nbd_getlength,
|
.bdrv_getlength = nbd_getlength,
|
||||||
|
.bdrv_detach_aio_context = nbd_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = nbd_attach_aio_context,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void bdrv_nbd_init(void)
|
static void bdrv_nbd_init(void)
|
||||||
|
|||||||
89
block/nfs.c
89
block/nfs.c
@@ -40,6 +40,7 @@ typedef struct NFSClient {
|
|||||||
struct nfsfh *fh;
|
struct nfsfh *fh;
|
||||||
int events;
|
int events;
|
||||||
bool has_zero_init;
|
bool has_zero_init;
|
||||||
|
AioContext *aio_context;
|
||||||
} NFSClient;
|
} NFSClient;
|
||||||
|
|
||||||
typedef struct NFSRPC {
|
typedef struct NFSRPC {
|
||||||
@@ -49,6 +50,7 @@ typedef struct NFSRPC {
|
|||||||
struct stat *st;
|
struct stat *st;
|
||||||
Coroutine *co;
|
Coroutine *co;
|
||||||
QEMUBH *bh;
|
QEMUBH *bh;
|
||||||
|
NFSClient *client;
|
||||||
} NFSRPC;
|
} NFSRPC;
|
||||||
|
|
||||||
static void nfs_process_read(void *arg);
|
static void nfs_process_read(void *arg);
|
||||||
@@ -58,10 +60,11 @@ static void nfs_set_events(NFSClient *client)
|
|||||||
{
|
{
|
||||||
int ev = nfs_which_events(client->context);
|
int ev = nfs_which_events(client->context);
|
||||||
if (ev != client->events) {
|
if (ev != client->events) {
|
||||||
qemu_aio_set_fd_handler(nfs_get_fd(client->context),
|
aio_set_fd_handler(client->aio_context,
|
||||||
(ev & POLLIN) ? nfs_process_read : NULL,
|
nfs_get_fd(client->context),
|
||||||
(ev & POLLOUT) ? nfs_process_write : NULL,
|
(ev & POLLIN) ? nfs_process_read : NULL,
|
||||||
client);
|
(ev & POLLOUT) ? nfs_process_write : NULL,
|
||||||
|
client);
|
||||||
|
|
||||||
}
|
}
|
||||||
client->events = ev;
|
client->events = ev;
|
||||||
@@ -84,13 +87,15 @@ static void nfs_process_write(void *arg)
|
|||||||
static void nfs_co_init_task(NFSClient *client, NFSRPC *task)
|
static void nfs_co_init_task(NFSClient *client, NFSRPC *task)
|
||||||
{
|
{
|
||||||
*task = (NFSRPC) {
|
*task = (NFSRPC) {
|
||||||
.co = qemu_coroutine_self(),
|
.co = qemu_coroutine_self(),
|
||||||
|
.client = client,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nfs_co_generic_bh_cb(void *opaque)
|
static void nfs_co_generic_bh_cb(void *opaque)
|
||||||
{
|
{
|
||||||
NFSRPC *task = opaque;
|
NFSRPC *task = opaque;
|
||||||
|
task->complete = 1;
|
||||||
qemu_bh_delete(task->bh);
|
qemu_bh_delete(task->bh);
|
||||||
qemu_coroutine_enter(task->co, NULL);
|
qemu_coroutine_enter(task->co, NULL);
|
||||||
}
|
}
|
||||||
@@ -100,7 +105,6 @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data,
|
|||||||
void *private_data)
|
void *private_data)
|
||||||
{
|
{
|
||||||
NFSRPC *task = private_data;
|
NFSRPC *task = private_data;
|
||||||
task->complete = 1;
|
|
||||||
task->ret = ret;
|
task->ret = ret;
|
||||||
if (task->ret > 0 && task->iov) {
|
if (task->ret > 0 && task->iov) {
|
||||||
if (task->ret <= task->iov->size) {
|
if (task->ret <= task->iov->size) {
|
||||||
@@ -116,8 +120,11 @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data,
|
|||||||
error_report("NFS Error: %s", nfs_get_error(nfs));
|
error_report("NFS Error: %s", nfs_get_error(nfs));
|
||||||
}
|
}
|
||||||
if (task->co) {
|
if (task->co) {
|
||||||
task->bh = qemu_bh_new(nfs_co_generic_bh_cb, task);
|
task->bh = aio_bh_new(task->client->aio_context,
|
||||||
|
nfs_co_generic_bh_cb, task);
|
||||||
qemu_bh_schedule(task->bh);
|
qemu_bh_schedule(task->bh);
|
||||||
|
} else {
|
||||||
|
task->complete = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,13 +231,34 @@ static QemuOptsList runtime_opts = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void nfs_detach_aio_context(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
NFSClient *client = bs->opaque;
|
||||||
|
|
||||||
|
aio_set_fd_handler(client->aio_context,
|
||||||
|
nfs_get_fd(client->context),
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
client->events = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nfs_attach_aio_context(BlockDriverState *bs,
|
||||||
|
AioContext *new_context)
|
||||||
|
{
|
||||||
|
NFSClient *client = bs->opaque;
|
||||||
|
|
||||||
|
client->aio_context = new_context;
|
||||||
|
nfs_set_events(client);
|
||||||
|
}
|
||||||
|
|
||||||
static void nfs_client_close(NFSClient *client)
|
static void nfs_client_close(NFSClient *client)
|
||||||
{
|
{
|
||||||
if (client->context) {
|
if (client->context) {
|
||||||
if (client->fh) {
|
if (client->fh) {
|
||||||
nfs_close(client->context, client->fh);
|
nfs_close(client->context, client->fh);
|
||||||
}
|
}
|
||||||
qemu_aio_set_fd_handler(nfs_get_fd(client->context), NULL, NULL, NULL);
|
aio_set_fd_handler(client->aio_context,
|
||||||
|
nfs_get_fd(client->context),
|
||||||
|
NULL, NULL, NULL);
|
||||||
nfs_destroy_context(client->context);
|
nfs_destroy_context(client->context);
|
||||||
}
|
}
|
||||||
memset(client, 0, sizeof(NFSClient));
|
memset(client, 0, sizeof(NFSClient));
|
||||||
@@ -345,6 +373,8 @@ static int nfs_file_open(BlockDriverState *bs, QDict *options, int flags,
|
|||||||
QemuOpts *opts;
|
QemuOpts *opts;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
|
client->aio_context = bdrv_get_aio_context(bs);
|
||||||
|
|
||||||
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
|
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
|
||||||
qemu_opts_absorb_qdict(opts, options, &local_err);
|
qemu_opts_absorb_qdict(opts, options, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
@@ -361,20 +391,16 @@ static int nfs_file_open(BlockDriverState *bs, QDict *options, int flags,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nfs_file_create(const char *url, QEMUOptionParameter *options,
|
static int nfs_file_create(const char *url, QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int64_t total_size = 0;
|
int64_t total_size = 0;
|
||||||
NFSClient *client = g_malloc0(sizeof(NFSClient));
|
NFSClient *client = g_malloc0(sizeof(NFSClient));
|
||||||
|
|
||||||
|
client->aio_context = qemu_get_aio_context();
|
||||||
|
|
||||||
/* Read out options */
|
/* Read out options */
|
||||||
while (options && options->name) {
|
total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
|
||||||
if (!strcmp(options->name, "size")) {
|
|
||||||
total_size = options->value.n;
|
|
||||||
}
|
|
||||||
options++;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = nfs_client_open(client, url, O_CREAT, errp);
|
ret = nfs_client_open(client, url, O_CREAT, errp);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -407,7 +433,7 @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
|
|||||||
|
|
||||||
while (!task.complete) {
|
while (!task.complete) {
|
||||||
nfs_set_events(client);
|
nfs_set_events(client);
|
||||||
qemu_aio_wait();
|
aio_poll(client->aio_context, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (task.ret < 0 ? task.ret : st.st_blocks * st.st_blksize);
|
return (task.ret < 0 ? task.ret : st.st_blocks * st.st_blksize);
|
||||||
@@ -420,22 +446,25 @@ static int nfs_file_truncate(BlockDriverState *bs, int64_t offset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static BlockDriver bdrv_nfs = {
|
static BlockDriver bdrv_nfs = {
|
||||||
.format_name = "nfs",
|
.format_name = "nfs",
|
||||||
.protocol_name = "nfs",
|
.protocol_name = "nfs",
|
||||||
|
|
||||||
.instance_size = sizeof(NFSClient),
|
.instance_size = sizeof(NFSClient),
|
||||||
.bdrv_needs_filename = true,
|
.bdrv_needs_filename = true,
|
||||||
.bdrv_has_zero_init = nfs_has_zero_init,
|
.bdrv_has_zero_init = nfs_has_zero_init,
|
||||||
.bdrv_get_allocated_file_size = nfs_get_allocated_file_size,
|
.bdrv_get_allocated_file_size = nfs_get_allocated_file_size,
|
||||||
.bdrv_truncate = nfs_file_truncate,
|
.bdrv_truncate = nfs_file_truncate,
|
||||||
|
|
||||||
.bdrv_file_open = nfs_file_open,
|
.bdrv_file_open = nfs_file_open,
|
||||||
.bdrv_close = nfs_file_close,
|
.bdrv_close = nfs_file_close,
|
||||||
.bdrv_create = nfs_file_create,
|
.bdrv_create = nfs_file_create,
|
||||||
|
|
||||||
.bdrv_co_readv = nfs_co_readv,
|
.bdrv_co_readv = nfs_co_readv,
|
||||||
.bdrv_co_writev = nfs_co_writev,
|
.bdrv_co_writev = nfs_co_writev,
|
||||||
.bdrv_co_flush_to_disk = nfs_co_flush,
|
.bdrv_co_flush_to_disk = nfs_co_flush,
|
||||||
|
|
||||||
|
.bdrv_detach_aio_context = nfs_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = nfs_attach_aio_context,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void nfs_block_init(void)
|
static void nfs_block_init(void)
|
||||||
|
|||||||
72
block/qcow.c
72
block/qcow.c
@@ -693,35 +693,29 @@ static void qcow_close(BlockDriverState *bs)
|
|||||||
error_free(s->migration_blocker);
|
error_free(s->migration_blocker);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow_create(const char *filename, QEMUOptionParameter *options,
|
static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
int header_size, backing_filename_len, l1_size, shift, i;
|
int header_size, backing_filename_len, l1_size, shift, i;
|
||||||
QCowHeader header;
|
QCowHeader header;
|
||||||
uint8_t *tmp;
|
uint8_t *tmp;
|
||||||
int64_t total_size = 0;
|
int64_t total_size = 0;
|
||||||
const char *backing_file = NULL;
|
char *backing_file = NULL;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
BlockDriverState *qcow_bs;
|
BlockDriverState *qcow_bs;
|
||||||
|
|
||||||
/* Read out options */
|
/* Read out options */
|
||||||
while (options && options->name) {
|
total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
|
||||||
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
|
backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
|
||||||
total_size = options->value.n / 512;
|
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
|
flags |= BLOCK_FLAG_ENCRYPT;
|
||||||
backing_file = options->value.s;
|
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) {
|
|
||||||
flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0;
|
|
||||||
}
|
|
||||||
options++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bdrv_create_file(filename, options, &local_err);
|
ret = bdrv_create_file(filename, opts, &local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
return ret;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
qcow_bs = NULL;
|
qcow_bs = NULL;
|
||||||
@@ -729,7 +723,7 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err);
|
BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
return ret;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bdrv_truncate(qcow_bs, 0);
|
ret = bdrv_truncate(qcow_bs, 0);
|
||||||
@@ -800,6 +794,8 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
ret = 0;
|
ret = 0;
|
||||||
exit:
|
exit:
|
||||||
bdrv_unref(qcow_bs);
|
bdrv_unref(qcow_bs);
|
||||||
|
cleanup:
|
||||||
|
g_free(backing_file);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -912,24 +908,28 @@ static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QemuOptsList qcow_create_opts = {
|
||||||
static QEMUOptionParameter qcow_create_options[] = {
|
.name = "qcow-create-opts",
|
||||||
{
|
.head = QTAILQ_HEAD_INITIALIZER(qcow_create_opts.head),
|
||||||
.name = BLOCK_OPT_SIZE,
|
.desc = {
|
||||||
.type = OPT_SIZE,
|
{
|
||||||
.help = "Virtual disk size"
|
.name = BLOCK_OPT_SIZE,
|
||||||
},
|
.type = QEMU_OPT_SIZE,
|
||||||
{
|
.help = "Virtual disk size"
|
||||||
.name = BLOCK_OPT_BACKING_FILE,
|
},
|
||||||
.type = OPT_STRING,
|
{
|
||||||
.help = "File name of a base image"
|
.name = BLOCK_OPT_BACKING_FILE,
|
||||||
},
|
.type = QEMU_OPT_STRING,
|
||||||
{
|
.help = "File name of a base image"
|
||||||
.name = BLOCK_OPT_ENCRYPT,
|
},
|
||||||
.type = OPT_FLAG,
|
{
|
||||||
.help = "Encrypt the image"
|
.name = BLOCK_OPT_ENCRYPT,
|
||||||
},
|
.type = QEMU_OPT_BOOL,
|
||||||
{ NULL }
|
.help = "Encrypt the image",
|
||||||
|
.def_value_str = "off"
|
||||||
|
},
|
||||||
|
{ /* end of list */ }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_qcow = {
|
static BlockDriver bdrv_qcow = {
|
||||||
@@ -938,8 +938,8 @@ static BlockDriver bdrv_qcow = {
|
|||||||
.bdrv_probe = qcow_probe,
|
.bdrv_probe = qcow_probe,
|
||||||
.bdrv_open = qcow_open,
|
.bdrv_open = qcow_open,
|
||||||
.bdrv_close = qcow_close,
|
.bdrv_close = qcow_close,
|
||||||
.bdrv_reopen_prepare = qcow_reopen_prepare,
|
.bdrv_reopen_prepare = qcow_reopen_prepare,
|
||||||
.bdrv_create = qcow_create,
|
.bdrv_create = qcow_create,
|
||||||
.bdrv_has_zero_init = bdrv_has_zero_init_1,
|
.bdrv_has_zero_init = bdrv_has_zero_init_1,
|
||||||
|
|
||||||
.bdrv_co_readv = qcow_co_readv,
|
.bdrv_co_readv = qcow_co_readv,
|
||||||
@@ -951,7 +951,7 @@ static BlockDriver bdrv_qcow = {
|
|||||||
.bdrv_write_compressed = qcow_write_compressed,
|
.bdrv_write_compressed = qcow_write_compressed,
|
||||||
.bdrv_get_info = qcow_get_info,
|
.bdrv_get_info = qcow_get_info,
|
||||||
|
|
||||||
.create_options = qcow_create_options,
|
.create_opts = &qcow_create_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void bdrv_qcow_init(void)
|
static void bdrv_qcow_init(void)
|
||||||
|
|||||||
259
block/qcow2.c
259
block/qcow2.c
@@ -31,6 +31,7 @@
|
|||||||
#include "qapi/qmp/qerror.h"
|
#include "qapi/qmp/qerror.h"
|
||||||
#include "qapi/qmp/qbool.h"
|
#include "qapi/qmp/qbool.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
#include "qemu/option_int.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Differences with QCOW:
|
Differences with QCOW:
|
||||||
@@ -1594,7 +1595,7 @@ static int preallocate(BlockDriverState *bs)
|
|||||||
static int qcow2_create2(const char *filename, int64_t total_size,
|
static int qcow2_create2(const char *filename, int64_t total_size,
|
||||||
const char *backing_file, const char *backing_format,
|
const char *backing_file, const char *backing_format,
|
||||||
int flags, size_t cluster_size, int prealloc,
|
int flags, size_t cluster_size, int prealloc,
|
||||||
QEMUOptionParameter *options, int version,
|
QemuOpts *opts, int version,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
/* Calculate cluster_bits */
|
/* Calculate cluster_bits */
|
||||||
@@ -1626,7 +1627,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
|
|||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = bdrv_create_file(filename, options, &local_err);
|
ret = bdrv_create_file(filename, opts, &local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -1762,11 +1763,11 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow2_create(const char *filename, QEMUOptionParameter *options,
|
static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
const char *backing_file = NULL;
|
char *backing_file = NULL;
|
||||||
const char *backing_fmt = NULL;
|
char *backing_fmt = NULL;
|
||||||
|
char *buf = NULL;
|
||||||
uint64_t sectors = 0;
|
uint64_t sectors = 0;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
size_t cluster_size = DEFAULT_CLUSTER_SIZE;
|
size_t cluster_size = DEFAULT_CLUSTER_SIZE;
|
||||||
@@ -1776,64 +1777,66 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Read out options */
|
/* Read out options */
|
||||||
while (options && options->name) {
|
sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
|
||||||
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
|
backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
|
||||||
sectors = options->value.n / 512;
|
backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
|
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
|
||||||
backing_file = options->value.s;
|
flags |= BLOCK_FLAG_ENCRYPT;
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FMT)) {
|
}
|
||||||
backing_fmt = options->value.s;
|
cluster_size = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE,
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) {
|
DEFAULT_CLUSTER_SIZE);
|
||||||
flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0;
|
buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
|
if (!buf || !strcmp(buf, "off")) {
|
||||||
if (options->value.n) {
|
prealloc = 0;
|
||||||
cluster_size = options->value.n;
|
} else if (!strcmp(buf, "metadata")) {
|
||||||
}
|
prealloc = 1;
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
|
} else {
|
||||||
if (!options->value.s || !strcmp(options->value.s, "off")) {
|
error_setg(errp, "Invalid preallocation mode: '%s'", buf);
|
||||||
prealloc = 0;
|
ret = -EINVAL;
|
||||||
} else if (!strcmp(options->value.s, "metadata")) {
|
goto finish;
|
||||||
prealloc = 1;
|
}
|
||||||
} else {
|
g_free(buf);
|
||||||
error_setg(errp, "Invalid preallocation mode: '%s'",
|
buf = qemu_opt_get_del(opts, BLOCK_OPT_COMPAT_LEVEL);
|
||||||
options->value.s);
|
if (!buf) {
|
||||||
return -EINVAL;
|
/* keep the default */
|
||||||
}
|
} else if (!strcmp(buf, "0.10")) {
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_COMPAT_LEVEL)) {
|
version = 2;
|
||||||
if (!options->value.s) {
|
} else if (!strcmp(buf, "1.1")) {
|
||||||
/* keep the default */
|
version = 3;
|
||||||
} else if (!strcmp(options->value.s, "0.10")) {
|
} else {
|
||||||
version = 2;
|
error_setg(errp, "Invalid compatibility level: '%s'", buf);
|
||||||
} else if (!strcmp(options->value.s, "1.1")) {
|
ret = -EINVAL;
|
||||||
version = 3;
|
goto finish;
|
||||||
} else {
|
}
|
||||||
error_setg(errp, "Invalid compatibility level: '%s'",
|
|
||||||
options->value.s);
|
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_LAZY_REFCOUNTS, false)) {
|
||||||
return -EINVAL;
|
flags |= BLOCK_FLAG_LAZY_REFCOUNTS;
|
||||||
}
|
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_LAZY_REFCOUNTS)) {
|
|
||||||
flags |= options->value.n ? BLOCK_FLAG_LAZY_REFCOUNTS : 0;
|
|
||||||
}
|
|
||||||
options++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (backing_file && prealloc) {
|
if (backing_file && prealloc) {
|
||||||
error_setg(errp, "Backing file and preallocation cannot be used at "
|
error_setg(errp, "Backing file and preallocation cannot be used at "
|
||||||
"the same time");
|
"the same time");
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version < 3 && (flags & BLOCK_FLAG_LAZY_REFCOUNTS)) {
|
if (version < 3 && (flags & BLOCK_FLAG_LAZY_REFCOUNTS)) {
|
||||||
error_setg(errp, "Lazy refcounts only supported with compatibility "
|
error_setg(errp, "Lazy refcounts only supported with compatibility "
|
||||||
"level 1.1 and above (use compat=1.1 or greater)");
|
"level 1.1 and above (use compat=1.1 or greater)");
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = qcow2_create2(filename, sectors, backing_file, backing_fmt, flags,
|
ret = qcow2_create2(filename, sectors, backing_file, backing_fmt, flags,
|
||||||
cluster_size, prealloc, options, version, &local_err);
|
cluster_size, prealloc, opts, version, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finish:
|
||||||
|
g_free(backing_file);
|
||||||
|
g_free(backing_fmt);
|
||||||
|
g_free(buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2198,64 +2201,72 @@ static int qcow2_downgrade(BlockDriverState *bs, int target_version)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qcow2_amend_options(BlockDriverState *bs,
|
static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts)
|
||||||
QEMUOptionParameter *options)
|
|
||||||
{
|
{
|
||||||
BDRVQcowState *s = bs->opaque;
|
BDRVQcowState *s = bs->opaque;
|
||||||
int old_version = s->qcow_version, new_version = old_version;
|
int old_version = s->qcow_version, new_version = old_version;
|
||||||
uint64_t new_size = 0;
|
uint64_t new_size = 0;
|
||||||
const char *backing_file = NULL, *backing_format = NULL;
|
const char *backing_file = NULL, *backing_format = NULL;
|
||||||
bool lazy_refcounts = s->use_lazy_refcounts;
|
bool lazy_refcounts = s->use_lazy_refcounts;
|
||||||
|
const char *compat = NULL;
|
||||||
|
uint64_t cluster_size = s->cluster_size;
|
||||||
|
bool encrypt;
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
QemuOptDesc *desc = opts->list->desc;
|
||||||
|
|
||||||
for (i = 0; options[i].name; i++)
|
while (desc && desc->name) {
|
||||||
{
|
if (!qemu_opt_find(opts, desc->name)) {
|
||||||
if (!options[i].assigned) {
|
|
||||||
/* only change explicitly defined options */
|
/* only change explicitly defined options */
|
||||||
|
desc++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(options[i].name, "compat")) {
|
if (!strcmp(desc->name, "compat")) {
|
||||||
if (!options[i].value.s) {
|
compat = qemu_opt_get(opts, "compat");
|
||||||
|
if (!compat) {
|
||||||
/* preserve default */
|
/* preserve default */
|
||||||
} else if (!strcmp(options[i].value.s, "0.10")) {
|
} else if (!strcmp(compat, "0.10")) {
|
||||||
new_version = 2;
|
new_version = 2;
|
||||||
} else if (!strcmp(options[i].value.s, "1.1")) {
|
} else if (!strcmp(compat, "1.1")) {
|
||||||
new_version = 3;
|
new_version = 3;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Unknown compatibility level %s.\n",
|
fprintf(stderr, "Unknown compatibility level %s.\n", compat);
|
||||||
options[i].value.s);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(options[i].name, "preallocation")) {
|
} else if (!strcmp(desc->name, "preallocation")) {
|
||||||
fprintf(stderr, "Cannot change preallocation mode.\n");
|
fprintf(stderr, "Cannot change preallocation mode.\n");
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
} else if (!strcmp(options[i].name, "size")) {
|
} else if (!strcmp(desc->name, "size")) {
|
||||||
new_size = options[i].value.n;
|
new_size = qemu_opt_get_size(opts, "size", 0);
|
||||||
} else if (!strcmp(options[i].name, "backing_file")) {
|
} else if (!strcmp(desc->name, "backing_file")) {
|
||||||
backing_file = options[i].value.s;
|
backing_file = qemu_opt_get(opts, "backing_file");
|
||||||
} else if (!strcmp(options[i].name, "backing_fmt")) {
|
} else if (!strcmp(desc->name, "backing_fmt")) {
|
||||||
backing_format = options[i].value.s;
|
backing_format = qemu_opt_get(opts, "backing_fmt");
|
||||||
} else if (!strcmp(options[i].name, "encryption")) {
|
} else if (!strcmp(desc->name, "encryption")) {
|
||||||
if ((options[i].value.n != !!s->crypt_method)) {
|
encrypt = qemu_opt_get_bool(opts, "encryption", s->crypt_method);
|
||||||
|
if (encrypt != !!s->crypt_method) {
|
||||||
fprintf(stderr, "Changing the encryption flag is not "
|
fprintf(stderr, "Changing the encryption flag is not "
|
||||||
"supported.\n");
|
"supported.\n");
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(options[i].name, "cluster_size")) {
|
} else if (!strcmp(desc->name, "cluster_size")) {
|
||||||
if (options[i].value.n != s->cluster_size) {
|
cluster_size = qemu_opt_get_size(opts, "cluster_size",
|
||||||
|
cluster_size);
|
||||||
|
if (cluster_size != s->cluster_size) {
|
||||||
fprintf(stderr, "Changing the cluster size is not "
|
fprintf(stderr, "Changing the cluster size is not "
|
||||||
"supported.\n");
|
"supported.\n");
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
} else if (!strcmp(options[i].name, "lazy_refcounts")) {
|
} else if (!strcmp(desc->name, "lazy_refcounts")) {
|
||||||
lazy_refcounts = options[i].value.n;
|
lazy_refcounts = qemu_opt_get_bool(opts, "lazy_refcounts",
|
||||||
|
lazy_refcounts);
|
||||||
} else {
|
} else {
|
||||||
/* if this assertion fails, this probably means a new option was
|
/* if this assertion fails, this probably means a new option was
|
||||||
* added without having it covered here */
|
* added without having it covered here */
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
desc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_version != old_version) {
|
if (new_version != old_version) {
|
||||||
@@ -2324,49 +2335,55 @@ static int qcow2_amend_options(BlockDriverState *bs,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QEMUOptionParameter qcow2_create_options[] = {
|
static QemuOptsList qcow2_create_opts = {
|
||||||
{
|
.name = "qcow2-create-opts",
|
||||||
.name = BLOCK_OPT_SIZE,
|
.head = QTAILQ_HEAD_INITIALIZER(qcow2_create_opts.head),
|
||||||
.type = OPT_SIZE,
|
.desc = {
|
||||||
.help = "Virtual disk size"
|
{
|
||||||
},
|
.name = BLOCK_OPT_SIZE,
|
||||||
{
|
.type = QEMU_OPT_SIZE,
|
||||||
.name = BLOCK_OPT_COMPAT_LEVEL,
|
.help = "Virtual disk size"
|
||||||
.type = OPT_STRING,
|
},
|
||||||
.help = "Compatibility level (0.10 or 1.1)"
|
{
|
||||||
},
|
.name = BLOCK_OPT_COMPAT_LEVEL,
|
||||||
{
|
.type = QEMU_OPT_STRING,
|
||||||
.name = BLOCK_OPT_BACKING_FILE,
|
.help = "Compatibility level (0.10 or 1.1)"
|
||||||
.type = OPT_STRING,
|
},
|
||||||
.help = "File name of a base image"
|
{
|
||||||
},
|
.name = BLOCK_OPT_BACKING_FILE,
|
||||||
{
|
.type = QEMU_OPT_STRING,
|
||||||
.name = BLOCK_OPT_BACKING_FMT,
|
.help = "File name of a base image"
|
||||||
.type = OPT_STRING,
|
},
|
||||||
.help = "Image format of the base image"
|
{
|
||||||
},
|
.name = BLOCK_OPT_BACKING_FMT,
|
||||||
{
|
.type = QEMU_OPT_STRING,
|
||||||
.name = BLOCK_OPT_ENCRYPT,
|
.help = "Image format of the base image"
|
||||||
.type = OPT_FLAG,
|
},
|
||||||
.help = "Encrypt the image"
|
{
|
||||||
},
|
.name = BLOCK_OPT_ENCRYPT,
|
||||||
{
|
.type = QEMU_OPT_BOOL,
|
||||||
.name = BLOCK_OPT_CLUSTER_SIZE,
|
.help = "Encrypt the image",
|
||||||
.type = OPT_SIZE,
|
.def_value_str = "off"
|
||||||
.help = "qcow2 cluster size",
|
},
|
||||||
.value = { .n = DEFAULT_CLUSTER_SIZE },
|
{
|
||||||
},
|
.name = BLOCK_OPT_CLUSTER_SIZE,
|
||||||
{
|
.type = QEMU_OPT_SIZE,
|
||||||
.name = BLOCK_OPT_PREALLOC,
|
.help = "qcow2 cluster size",
|
||||||
.type = OPT_STRING,
|
.def_value_str = stringify(DEFAULT_CLUSTER_SIZE)
|
||||||
.help = "Preallocation mode (allowed values: off, metadata)"
|
},
|
||||||
},
|
{
|
||||||
{
|
.name = BLOCK_OPT_PREALLOC,
|
||||||
.name = BLOCK_OPT_LAZY_REFCOUNTS,
|
.type = QEMU_OPT_STRING,
|
||||||
.type = OPT_FLAG,
|
.help = "Preallocation mode (allowed values: off, metadata)"
|
||||||
.help = "Postpone refcount updates",
|
},
|
||||||
},
|
{
|
||||||
{ NULL }
|
.name = BLOCK_OPT_LAZY_REFCOUNTS,
|
||||||
|
.type = QEMU_OPT_BOOL,
|
||||||
|
.help = "Postpone refcount updates",
|
||||||
|
.def_value_str = "off"
|
||||||
|
},
|
||||||
|
{ /* end of list */ }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_qcow2 = {
|
static BlockDriver bdrv_qcow2 = {
|
||||||
@@ -2394,8 +2411,8 @@ static BlockDriver bdrv_qcow2 = {
|
|||||||
.bdrv_snapshot_goto = qcow2_snapshot_goto,
|
.bdrv_snapshot_goto = qcow2_snapshot_goto,
|
||||||
.bdrv_snapshot_delete = qcow2_snapshot_delete,
|
.bdrv_snapshot_delete = qcow2_snapshot_delete,
|
||||||
.bdrv_snapshot_list = qcow2_snapshot_list,
|
.bdrv_snapshot_list = qcow2_snapshot_list,
|
||||||
.bdrv_snapshot_load_tmp = qcow2_snapshot_load_tmp,
|
.bdrv_snapshot_load_tmp = qcow2_snapshot_load_tmp,
|
||||||
.bdrv_get_info = qcow2_get_info,
|
.bdrv_get_info = qcow2_get_info,
|
||||||
.bdrv_get_specific_info = qcow2_get_specific_info,
|
.bdrv_get_specific_info = qcow2_get_specific_info,
|
||||||
|
|
||||||
.bdrv_save_vmstate = qcow2_save_vmstate,
|
.bdrv_save_vmstate = qcow2_save_vmstate,
|
||||||
@@ -2406,9 +2423,9 @@ static BlockDriver bdrv_qcow2 = {
|
|||||||
.bdrv_refresh_limits = qcow2_refresh_limits,
|
.bdrv_refresh_limits = qcow2_refresh_limits,
|
||||||
.bdrv_invalidate_cache = qcow2_invalidate_cache,
|
.bdrv_invalidate_cache = qcow2_invalidate_cache,
|
||||||
|
|
||||||
.create_options = qcow2_create_options,
|
.create_opts = &qcow2_create_opts,
|
||||||
.bdrv_check = qcow2_check,
|
.bdrv_check = qcow2_check,
|
||||||
.bdrv_amend_options = qcow2_amend_options,
|
.bdrv_amend_options = qcow2_amend_options,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void bdrv_qcow2_init(void)
|
static void bdrv_qcow2_init(void)
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ int qed_read_l1_table_sync(BDRVQEDState *s)
|
|||||||
qed_read_table(s, s->header.l1_table_offset,
|
qed_read_table(s, s->header.l1_table_offset,
|
||||||
s->l1_table, qed_sync_cb, &ret);
|
s->l1_table, qed_sync_cb, &ret);
|
||||||
while (ret == -EINPROGRESS) {
|
while (ret == -EINPROGRESS) {
|
||||||
qemu_aio_wait();
|
aio_poll(bdrv_get_aio_context(s->bs), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -194,7 +194,7 @@ int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
|
|||||||
|
|
||||||
qed_write_l1_table(s, index, n, qed_sync_cb, &ret);
|
qed_write_l1_table(s, index, n, qed_sync_cb, &ret);
|
||||||
while (ret == -EINPROGRESS) {
|
while (ret == -EINPROGRESS) {
|
||||||
qemu_aio_wait();
|
aio_poll(bdrv_get_aio_context(s->bs), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -267,7 +267,7 @@ int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset
|
|||||||
|
|
||||||
qed_read_l2_table(s, request, offset, qed_sync_cb, &ret);
|
qed_read_l2_table(s, request, offset, qed_sync_cb, &ret);
|
||||||
while (ret == -EINPROGRESS) {
|
while (ret == -EINPROGRESS) {
|
||||||
qemu_aio_wait();
|
aio_poll(bdrv_get_aio_context(s->bs), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -289,7 +289,7 @@ int qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
|
|||||||
|
|
||||||
qed_write_l2_table(s, request, index, n, flush, qed_sync_cb, &ret);
|
qed_write_l2_table(s, request, index, n, flush, qed_sync_cb, &ret);
|
||||||
while (ret == -EINPROGRESS) {
|
while (ret == -EINPROGRESS) {
|
||||||
qemu_aio_wait();
|
aio_poll(bdrv_get_aio_context(s->bs), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
145
block/qed.c
145
block/qed.c
@@ -21,12 +21,13 @@
|
|||||||
static void qed_aio_cancel(BlockDriverAIOCB *blockacb)
|
static void qed_aio_cancel(BlockDriverAIOCB *blockacb)
|
||||||
{
|
{
|
||||||
QEDAIOCB *acb = (QEDAIOCB *)blockacb;
|
QEDAIOCB *acb = (QEDAIOCB *)blockacb;
|
||||||
|
AioContext *aio_context = bdrv_get_aio_context(blockacb->bs);
|
||||||
bool finished = false;
|
bool finished = false;
|
||||||
|
|
||||||
/* Wait for the request to finish */
|
/* Wait for the request to finish */
|
||||||
acb->finished = &finished;
|
acb->finished = &finished;
|
||||||
while (!finished) {
|
while (!finished) {
|
||||||
qemu_aio_wait();
|
aio_poll(aio_context, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,6 +374,27 @@ static void bdrv_qed_rebind(BlockDriverState *bs)
|
|||||||
s->bs = bs;
|
s->bs = bs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bdrv_qed_detach_aio_context(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
BDRVQEDState *s = bs->opaque;
|
||||||
|
|
||||||
|
qed_cancel_need_check_timer(s);
|
||||||
|
timer_free(s->need_check_timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bdrv_qed_attach_aio_context(BlockDriverState *bs,
|
||||||
|
AioContext *new_context)
|
||||||
|
{
|
||||||
|
BDRVQEDState *s = bs->opaque;
|
||||||
|
|
||||||
|
s->need_check_timer = aio_timer_new(new_context,
|
||||||
|
QEMU_CLOCK_VIRTUAL, SCALE_NS,
|
||||||
|
qed_need_check_timer_cb, s);
|
||||||
|
if (s->header.features & QED_F_NEED_CHECK) {
|
||||||
|
qed_start_need_check_timer(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
|
static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
@@ -496,8 +518,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s->need_check_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
|
bdrv_qed_attach_aio_context(bs, bdrv_get_aio_context(bs));
|
||||||
qed_need_check_timer_cb, s);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -528,8 +549,7 @@ static void bdrv_qed_close(BlockDriverState *bs)
|
|||||||
{
|
{
|
||||||
BDRVQEDState *s = bs->opaque;
|
BDRVQEDState *s = bs->opaque;
|
||||||
|
|
||||||
qed_cancel_need_check_timer(s);
|
bdrv_qed_detach_aio_context(bs);
|
||||||
timer_free(s->need_check_timer);
|
|
||||||
|
|
||||||
/* Ensure writes reach stable storage */
|
/* Ensure writes reach stable storage */
|
||||||
bdrv_flush(bs->file);
|
bdrv_flush(bs->file);
|
||||||
@@ -621,55 +641,53 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bdrv_qed_create(const char *filename, QEMUOptionParameter *options,
|
static int bdrv_qed_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
uint64_t image_size = 0;
|
uint64_t image_size = 0;
|
||||||
uint32_t cluster_size = QED_DEFAULT_CLUSTER_SIZE;
|
uint32_t cluster_size = QED_DEFAULT_CLUSTER_SIZE;
|
||||||
uint32_t table_size = QED_DEFAULT_TABLE_SIZE;
|
uint32_t table_size = QED_DEFAULT_TABLE_SIZE;
|
||||||
const char *backing_file = NULL;
|
char *backing_file = NULL;
|
||||||
const char *backing_fmt = NULL;
|
char *backing_fmt = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
while (options && options->name) {
|
image_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
|
||||||
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
|
backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
|
||||||
image_size = options->value.n;
|
backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
|
cluster_size = qemu_opt_get_size_del(opts,
|
||||||
backing_file = options->value.s;
|
BLOCK_OPT_CLUSTER_SIZE,
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FMT)) {
|
QED_DEFAULT_CLUSTER_SIZE);
|
||||||
backing_fmt = options->value.s;
|
table_size = qemu_opt_get_size_del(opts, BLOCK_OPT_TABLE_SIZE,
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
|
QED_DEFAULT_TABLE_SIZE);
|
||||||
if (options->value.n) {
|
|
||||||
cluster_size = options->value.n;
|
|
||||||
}
|
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_TABLE_SIZE)) {
|
|
||||||
if (options->value.n) {
|
|
||||||
table_size = options->value.n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
options++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!qed_is_cluster_size_valid(cluster_size)) {
|
if (!qed_is_cluster_size_valid(cluster_size)) {
|
||||||
error_setg(errp, "QED cluster size must be within range [%u, %u] "
|
error_setg(errp, "QED cluster size must be within range [%u, %u] "
|
||||||
"and power of 2",
|
"and power of 2",
|
||||||
QED_MIN_CLUSTER_SIZE, QED_MAX_CLUSTER_SIZE);
|
QED_MIN_CLUSTER_SIZE, QED_MAX_CLUSTER_SIZE);
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto finish;
|
||||||
}
|
}
|
||||||
if (!qed_is_table_size_valid(table_size)) {
|
if (!qed_is_table_size_valid(table_size)) {
|
||||||
error_setg(errp, "QED table size must be within range [%u, %u] "
|
error_setg(errp, "QED table size must be within range [%u, %u] "
|
||||||
"and power of 2",
|
"and power of 2",
|
||||||
QED_MIN_TABLE_SIZE, QED_MAX_TABLE_SIZE);
|
QED_MIN_TABLE_SIZE, QED_MAX_TABLE_SIZE);
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto finish;
|
||||||
}
|
}
|
||||||
if (!qed_is_image_size_valid(image_size, cluster_size, table_size)) {
|
if (!qed_is_image_size_valid(image_size, cluster_size, table_size)) {
|
||||||
error_setg(errp, "QED image size must be a non-zero multiple of "
|
error_setg(errp, "QED image size must be a non-zero multiple of "
|
||||||
"cluster size and less than %" PRIu64 " bytes",
|
"cluster size and less than %" PRIu64 " bytes",
|
||||||
qed_max_image_size(cluster_size, table_size));
|
qed_max_image_size(cluster_size, table_size));
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
return qed_create(filename, cluster_size, image_size, table_size,
|
ret = qed_create(filename, cluster_size, image_size, table_size,
|
||||||
backing_file, backing_fmt, errp);
|
backing_file, backing_fmt, errp);
|
||||||
|
|
||||||
|
finish:
|
||||||
|
g_free(backing_file);
|
||||||
|
g_free(backing_fmt);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -919,7 +937,8 @@ static void qed_aio_complete(QEDAIOCB *acb, int ret)
|
|||||||
|
|
||||||
/* Arrange for a bh to invoke the completion function */
|
/* Arrange for a bh to invoke the completion function */
|
||||||
acb->bh_ret = ret;
|
acb->bh_ret = ret;
|
||||||
acb->bh = qemu_bh_new(qed_aio_complete_bh, acb);
|
acb->bh = aio_bh_new(bdrv_get_aio_context(acb->common.bs),
|
||||||
|
qed_aio_complete_bh, acb);
|
||||||
qemu_bh_schedule(acb->bh);
|
qemu_bh_schedule(acb->bh);
|
||||||
|
|
||||||
/* Start next allocating write request waiting behind this one. Note that
|
/* Start next allocating write request waiting behind this one. Note that
|
||||||
@@ -1595,36 +1614,44 @@ static int bdrv_qed_check(BlockDriverState *bs, BdrvCheckResult *result,
|
|||||||
return qed_check(s, result, !!fix);
|
return qed_check(s, result, !!fix);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QEMUOptionParameter qed_create_options[] = {
|
static QemuOptsList qed_create_opts = {
|
||||||
{
|
.name = "qed-create-opts",
|
||||||
.name = BLOCK_OPT_SIZE,
|
.head = QTAILQ_HEAD_INITIALIZER(qed_create_opts.head),
|
||||||
.type = OPT_SIZE,
|
.desc = {
|
||||||
.help = "Virtual disk size (in bytes)"
|
{
|
||||||
}, {
|
.name = BLOCK_OPT_SIZE,
|
||||||
.name = BLOCK_OPT_BACKING_FILE,
|
.type = QEMU_OPT_SIZE,
|
||||||
.type = OPT_STRING,
|
.help = "Virtual disk size"
|
||||||
.help = "File name of a base image"
|
},
|
||||||
}, {
|
{
|
||||||
.name = BLOCK_OPT_BACKING_FMT,
|
.name = BLOCK_OPT_BACKING_FILE,
|
||||||
.type = OPT_STRING,
|
.type = QEMU_OPT_STRING,
|
||||||
.help = "Image format of the base image"
|
.help = "File name of a base image"
|
||||||
}, {
|
},
|
||||||
.name = BLOCK_OPT_CLUSTER_SIZE,
|
{
|
||||||
.type = OPT_SIZE,
|
.name = BLOCK_OPT_BACKING_FMT,
|
||||||
.help = "Cluster size (in bytes)",
|
.type = QEMU_OPT_STRING,
|
||||||
.value = { .n = QED_DEFAULT_CLUSTER_SIZE },
|
.help = "Image format of the base image"
|
||||||
}, {
|
},
|
||||||
.name = BLOCK_OPT_TABLE_SIZE,
|
{
|
||||||
.type = OPT_SIZE,
|
.name = BLOCK_OPT_CLUSTER_SIZE,
|
||||||
.help = "L1/L2 table size (in clusters)"
|
.type = QEMU_OPT_SIZE,
|
||||||
},
|
.help = "Cluster size (in bytes)",
|
||||||
{ /* end of list */ }
|
.def_value_str = stringify(QED_DEFAULT_CLUSTER_SIZE)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = BLOCK_OPT_TABLE_SIZE,
|
||||||
|
.type = QEMU_OPT_SIZE,
|
||||||
|
.help = "L1/L2 table size (in clusters)"
|
||||||
|
},
|
||||||
|
{ /* end of list */ }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_qed = {
|
static BlockDriver bdrv_qed = {
|
||||||
.format_name = "qed",
|
.format_name = "qed",
|
||||||
.instance_size = sizeof(BDRVQEDState),
|
.instance_size = sizeof(BDRVQEDState),
|
||||||
.create_options = qed_create_options,
|
.create_opts = &qed_create_opts,
|
||||||
|
|
||||||
.bdrv_probe = bdrv_qed_probe,
|
.bdrv_probe = bdrv_qed_probe,
|
||||||
.bdrv_rebind = bdrv_qed_rebind,
|
.bdrv_rebind = bdrv_qed_rebind,
|
||||||
@@ -1644,6 +1671,8 @@ static BlockDriver bdrv_qed = {
|
|||||||
.bdrv_change_backing_file = bdrv_qed_change_backing_file,
|
.bdrv_change_backing_file = bdrv_qed_change_backing_file,
|
||||||
.bdrv_invalidate_cache = bdrv_qed_invalidate_cache,
|
.bdrv_invalidate_cache = bdrv_qed_invalidate_cache,
|
||||||
.bdrv_check = bdrv_qed_check,
|
.bdrv_check = bdrv_qed_check,
|
||||||
|
.bdrv_detach_aio_context = bdrv_qed_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = bdrv_qed_attach_aio_context,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void bdrv_qed_init(void)
|
static void bdrv_qed_init(void)
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
*
|
*
|
||||||
* All fields are little-endian on disk.
|
* All fields are little-endian on disk.
|
||||||
*/
|
*/
|
||||||
|
#define QED_DEFAULT_CLUSTER_SIZE 65536
|
||||||
enum {
|
enum {
|
||||||
QED_MAGIC = 'Q' | 'E' << 8 | 'D' << 16 | '\0' << 24,
|
QED_MAGIC = 'Q' | 'E' << 8 | 'D' << 16 | '\0' << 24,
|
||||||
|
|
||||||
@@ -69,7 +69,6 @@ enum {
|
|||||||
*/
|
*/
|
||||||
QED_MIN_CLUSTER_SIZE = 4 * 1024, /* in bytes */
|
QED_MIN_CLUSTER_SIZE = 4 * 1024, /* in bytes */
|
||||||
QED_MAX_CLUSTER_SIZE = 64 * 1024 * 1024,
|
QED_MAX_CLUSTER_SIZE = 64 * 1024 * 1024,
|
||||||
QED_DEFAULT_CLUSTER_SIZE = 64 * 1024,
|
|
||||||
|
|
||||||
/* Allocated clusters are tracked using a 2-level pagetable. Table size is
|
/* Allocated clusters are tracked using a 2-level pagetable. Table size is
|
||||||
* a multiple of clusters so large maximum image sizes can be supported
|
* a multiple of clusters so large maximum image sizes can be supported
|
||||||
|
|||||||
@@ -848,25 +848,49 @@ static void quorum_close(BlockDriverState *bs)
|
|||||||
g_free(s->bs);
|
g_free(s->bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void quorum_detach_aio_context(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
BDRVQuorumState *s = bs->opaque;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < s->num_children; i++) {
|
||||||
|
bdrv_detach_aio_context(s->bs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void quorum_attach_aio_context(BlockDriverState *bs,
|
||||||
|
AioContext *new_context)
|
||||||
|
{
|
||||||
|
BDRVQuorumState *s = bs->opaque;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < s->num_children; i++) {
|
||||||
|
bdrv_attach_aio_context(s->bs[i], new_context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static BlockDriver bdrv_quorum = {
|
static BlockDriver bdrv_quorum = {
|
||||||
.format_name = "quorum",
|
.format_name = "quorum",
|
||||||
.protocol_name = "quorum",
|
.protocol_name = "quorum",
|
||||||
|
|
||||||
.instance_size = sizeof(BDRVQuorumState),
|
.instance_size = sizeof(BDRVQuorumState),
|
||||||
|
|
||||||
.bdrv_file_open = quorum_open,
|
.bdrv_file_open = quorum_open,
|
||||||
.bdrv_close = quorum_close,
|
.bdrv_close = quorum_close,
|
||||||
|
|
||||||
.bdrv_co_flush_to_disk = quorum_co_flush,
|
.bdrv_co_flush_to_disk = quorum_co_flush,
|
||||||
|
|
||||||
.bdrv_getlength = quorum_getlength,
|
.bdrv_getlength = quorum_getlength,
|
||||||
|
|
||||||
.bdrv_aio_readv = quorum_aio_readv,
|
.bdrv_aio_readv = quorum_aio_readv,
|
||||||
.bdrv_aio_writev = quorum_aio_writev,
|
.bdrv_aio_writev = quorum_aio_writev,
|
||||||
.bdrv_invalidate_cache = quorum_invalidate_cache,
|
.bdrv_invalidate_cache = quorum_invalidate_cache,
|
||||||
|
|
||||||
.is_filter = true,
|
.bdrv_detach_aio_context = quorum_detach_aio_context,
|
||||||
.bdrv_recurse_is_first_non_filter = quorum_recurse_is_first_non_filter,
|
.bdrv_attach_aio_context = quorum_attach_aio_context,
|
||||||
|
|
||||||
|
.is_filter = true,
|
||||||
|
.bdrv_recurse_is_first_non_filter = quorum_recurse_is_first_non_filter,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void bdrv_quorum_init(void)
|
static void bdrv_quorum_init(void)
|
||||||
|
|||||||
@@ -34,19 +34,27 @@
|
|||||||
/* linux-aio.c - Linux native implementation */
|
/* linux-aio.c - Linux native implementation */
|
||||||
#ifdef CONFIG_LINUX_AIO
|
#ifdef CONFIG_LINUX_AIO
|
||||||
void *laio_init(void);
|
void *laio_init(void);
|
||||||
|
void laio_cleanup(void *s);
|
||||||
BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
|
BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
|
||||||
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
|
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
|
||||||
BlockDriverCompletionFunc *cb, void *opaque, int type);
|
BlockDriverCompletionFunc *cb, void *opaque, int type);
|
||||||
|
void laio_detach_aio_context(void *s, AioContext *old_context);
|
||||||
|
void laio_attach_aio_context(void *s, AioContext *new_context);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
typedef struct QEMUWin32AIOState QEMUWin32AIOState;
|
typedef struct QEMUWin32AIOState QEMUWin32AIOState;
|
||||||
QEMUWin32AIOState *win32_aio_init(void);
|
QEMUWin32AIOState *win32_aio_init(void);
|
||||||
|
void win32_aio_cleanup(QEMUWin32AIOState *aio);
|
||||||
int win32_aio_attach(QEMUWin32AIOState *aio, HANDLE hfile);
|
int win32_aio_attach(QEMUWin32AIOState *aio, HANDLE hfile);
|
||||||
BlockDriverAIOCB *win32_aio_submit(BlockDriverState *bs,
|
BlockDriverAIOCB *win32_aio_submit(BlockDriverState *bs,
|
||||||
QEMUWin32AIOState *aio, HANDLE hfile,
|
QEMUWin32AIOState *aio, HANDLE hfile,
|
||||||
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
|
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
|
||||||
BlockDriverCompletionFunc *cb, void *opaque, int type);
|
BlockDriverCompletionFunc *cb, void *opaque, int type);
|
||||||
|
void win32_aio_detach_aio_context(QEMUWin32AIOState *aio,
|
||||||
|
AioContext *old_context);
|
||||||
|
void win32_aio_attach_aio_context(QEMUWin32AIOState *aio,
|
||||||
|
AioContext *new_context);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* QEMU_RAW_AIO_H */
|
#endif /* QEMU_RAW_AIO_H */
|
||||||
|
|||||||
@@ -307,6 +307,29 @@ static void raw_parse_flags(int bdrv_flags, int *open_flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void raw_detach_aio_context(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_LINUX_AIO
|
||||||
|
BDRVRawState *s = bs->opaque;
|
||||||
|
|
||||||
|
if (s->use_aio) {
|
||||||
|
laio_detach_aio_context(s->aio_ctx, bdrv_get_aio_context(bs));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void raw_attach_aio_context(BlockDriverState *bs,
|
||||||
|
AioContext *new_context)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_LINUX_AIO
|
||||||
|
BDRVRawState *s = bs->opaque;
|
||||||
|
|
||||||
|
if (s->use_aio) {
|
||||||
|
laio_attach_aio_context(s->aio_ctx, new_context);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_LINUX_AIO
|
#ifdef CONFIG_LINUX_AIO
|
||||||
static int raw_set_aio(void **aio_ctx, int *use_aio, int bdrv_flags)
|
static int raw_set_aio(void **aio_ctx, int *use_aio, int bdrv_flags)
|
||||||
{
|
{
|
||||||
@@ -447,6 +470,8 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
raw_attach_aio_context(bs, bdrv_get_aio_context(bs));
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
fail:
|
fail:
|
||||||
if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
|
if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
|
||||||
@@ -1059,6 +1084,14 @@ static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs,
|
|||||||
static void raw_close(BlockDriverState *bs)
|
static void raw_close(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVRawState *s = bs->opaque;
|
BDRVRawState *s = bs->opaque;
|
||||||
|
|
||||||
|
raw_detach_aio_context(bs);
|
||||||
|
|
||||||
|
#ifdef CONFIG_LINUX_AIO
|
||||||
|
if (s->use_aio) {
|
||||||
|
laio_cleanup(s->aio_ctx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (s->fd >= 0) {
|
if (s->fd >= 0) {
|
||||||
qemu_close(s->fd);
|
qemu_close(s->fd);
|
||||||
s->fd = -1;
|
s->fd = -1;
|
||||||
@@ -1240,8 +1273,7 @@ static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
|
|||||||
return (int64_t)st.st_blocks * 512;
|
return (int64_t)st.st_blocks * 512;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int raw_create(const char *filename, QEMUOptionParameter *options,
|
static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
@@ -1250,12 +1282,8 @@ static int raw_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
strstart(filename, "file:", &filename);
|
strstart(filename, "file:", &filename);
|
||||||
|
|
||||||
/* Read out options */
|
/* Read out options */
|
||||||
while (options && options->name) {
|
total_size =
|
||||||
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
|
qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
|
||||||
total_size = options->value.n / BDRV_SECTOR_SIZE;
|
|
||||||
}
|
|
||||||
options++;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
|
fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
|
||||||
0644);
|
0644);
|
||||||
@@ -1440,13 +1468,17 @@ static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QEMUOptionParameter raw_create_options[] = {
|
static QemuOptsList raw_create_opts = {
|
||||||
{
|
.name = "raw-create-opts",
|
||||||
.name = BLOCK_OPT_SIZE,
|
.head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head),
|
||||||
.type = OPT_SIZE,
|
.desc = {
|
||||||
.help = "Virtual disk size"
|
{
|
||||||
},
|
.name = BLOCK_OPT_SIZE,
|
||||||
{ NULL }
|
.type = QEMU_OPT_SIZE,
|
||||||
|
.help = "Virtual disk size"
|
||||||
|
},
|
||||||
|
{ /* end of list */ }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_file = {
|
static BlockDriver bdrv_file = {
|
||||||
@@ -1478,7 +1510,10 @@ static BlockDriver bdrv_file = {
|
|||||||
.bdrv_get_allocated_file_size
|
.bdrv_get_allocated_file_size
|
||||||
= raw_get_allocated_file_size,
|
= raw_get_allocated_file_size,
|
||||||
|
|
||||||
.create_options = raw_create_options,
|
.bdrv_detach_aio_context = raw_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = raw_attach_aio_context,
|
||||||
|
|
||||||
|
.create_opts = &raw_create_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
/***********************************************/
|
/***********************************************/
|
||||||
@@ -1799,7 +1834,7 @@ static coroutine_fn int hdev_co_write_zeroes(BlockDriverState *bs,
|
|||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hdev_create(const char *filename, QEMUOptionParameter *options,
|
static int hdev_create(const char *filename, QemuOpts *opts,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
@@ -1820,12 +1855,8 @@ static int hdev_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
(void)has_prefix;
|
(void)has_prefix;
|
||||||
|
|
||||||
/* Read out options */
|
/* Read out options */
|
||||||
while (options && options->name) {
|
total_size =
|
||||||
if (!strcmp(options->name, "size")) {
|
qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
|
||||||
total_size = options->value.n / BDRV_SECTOR_SIZE;
|
|
||||||
}
|
|
||||||
options++;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = qemu_open(filename, O_WRONLY | O_BINARY);
|
fd = qemu_open(filename, O_WRONLY | O_BINARY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
@@ -1862,8 +1893,8 @@ static BlockDriver bdrv_host_device = {
|
|||||||
.bdrv_reopen_prepare = raw_reopen_prepare,
|
.bdrv_reopen_prepare = raw_reopen_prepare,
|
||||||
.bdrv_reopen_commit = raw_reopen_commit,
|
.bdrv_reopen_commit = raw_reopen_commit,
|
||||||
.bdrv_reopen_abort = raw_reopen_abort,
|
.bdrv_reopen_abort = raw_reopen_abort,
|
||||||
.bdrv_create = hdev_create,
|
.bdrv_create = hdev_create,
|
||||||
.create_options = raw_create_options,
|
.create_opts = &raw_create_opts,
|
||||||
.bdrv_co_write_zeroes = hdev_co_write_zeroes,
|
.bdrv_co_write_zeroes = hdev_co_write_zeroes,
|
||||||
|
|
||||||
.bdrv_aio_readv = raw_aio_readv,
|
.bdrv_aio_readv = raw_aio_readv,
|
||||||
@@ -1878,6 +1909,9 @@ static BlockDriver bdrv_host_device = {
|
|||||||
.bdrv_get_allocated_file_size
|
.bdrv_get_allocated_file_size
|
||||||
= raw_get_allocated_file_size,
|
= raw_get_allocated_file_size,
|
||||||
|
|
||||||
|
.bdrv_detach_aio_context = raw_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = raw_attach_aio_context,
|
||||||
|
|
||||||
/* generic scsi device */
|
/* generic scsi device */
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
.bdrv_ioctl = hdev_ioctl,
|
.bdrv_ioctl = hdev_ioctl,
|
||||||
@@ -2006,8 +2040,8 @@ static BlockDriver bdrv_host_floppy = {
|
|||||||
.bdrv_reopen_prepare = raw_reopen_prepare,
|
.bdrv_reopen_prepare = raw_reopen_prepare,
|
||||||
.bdrv_reopen_commit = raw_reopen_commit,
|
.bdrv_reopen_commit = raw_reopen_commit,
|
||||||
.bdrv_reopen_abort = raw_reopen_abort,
|
.bdrv_reopen_abort = raw_reopen_abort,
|
||||||
.bdrv_create = hdev_create,
|
.bdrv_create = hdev_create,
|
||||||
.create_options = raw_create_options,
|
.create_opts = &raw_create_opts,
|
||||||
|
|
||||||
.bdrv_aio_readv = raw_aio_readv,
|
.bdrv_aio_readv = raw_aio_readv,
|
||||||
.bdrv_aio_writev = raw_aio_writev,
|
.bdrv_aio_writev = raw_aio_writev,
|
||||||
@@ -2020,6 +2054,9 @@ static BlockDriver bdrv_host_floppy = {
|
|||||||
.bdrv_get_allocated_file_size
|
.bdrv_get_allocated_file_size
|
||||||
= raw_get_allocated_file_size,
|
= raw_get_allocated_file_size,
|
||||||
|
|
||||||
|
.bdrv_detach_aio_context = raw_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = raw_attach_aio_context,
|
||||||
|
|
||||||
/* removable device support */
|
/* removable device support */
|
||||||
.bdrv_is_inserted = floppy_is_inserted,
|
.bdrv_is_inserted = floppy_is_inserted,
|
||||||
.bdrv_media_changed = floppy_media_changed,
|
.bdrv_media_changed = floppy_media_changed,
|
||||||
@@ -2131,8 +2168,8 @@ static BlockDriver bdrv_host_cdrom = {
|
|||||||
.bdrv_reopen_prepare = raw_reopen_prepare,
|
.bdrv_reopen_prepare = raw_reopen_prepare,
|
||||||
.bdrv_reopen_commit = raw_reopen_commit,
|
.bdrv_reopen_commit = raw_reopen_commit,
|
||||||
.bdrv_reopen_abort = raw_reopen_abort,
|
.bdrv_reopen_abort = raw_reopen_abort,
|
||||||
.bdrv_create = hdev_create,
|
.bdrv_create = hdev_create,
|
||||||
.create_options = raw_create_options,
|
.create_opts = &raw_create_opts,
|
||||||
|
|
||||||
.bdrv_aio_readv = raw_aio_readv,
|
.bdrv_aio_readv = raw_aio_readv,
|
||||||
.bdrv_aio_writev = raw_aio_writev,
|
.bdrv_aio_writev = raw_aio_writev,
|
||||||
@@ -2145,6 +2182,9 @@ static BlockDriver bdrv_host_cdrom = {
|
|||||||
.bdrv_get_allocated_file_size
|
.bdrv_get_allocated_file_size
|
||||||
= raw_get_allocated_file_size,
|
= raw_get_allocated_file_size,
|
||||||
|
|
||||||
|
.bdrv_detach_aio_context = raw_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = raw_attach_aio_context,
|
||||||
|
|
||||||
/* removable device support */
|
/* removable device support */
|
||||||
.bdrv_is_inserted = cdrom_is_inserted,
|
.bdrv_is_inserted = cdrom_is_inserted,
|
||||||
.bdrv_eject = cdrom_eject,
|
.bdrv_eject = cdrom_eject,
|
||||||
@@ -2263,7 +2303,7 @@ static BlockDriver bdrv_host_cdrom = {
|
|||||||
.bdrv_reopen_commit = raw_reopen_commit,
|
.bdrv_reopen_commit = raw_reopen_commit,
|
||||||
.bdrv_reopen_abort = raw_reopen_abort,
|
.bdrv_reopen_abort = raw_reopen_abort,
|
||||||
.bdrv_create = hdev_create,
|
.bdrv_create = hdev_create,
|
||||||
.create_options = raw_create_options,
|
.create_opts = &raw_create_opts,
|
||||||
|
|
||||||
.bdrv_aio_readv = raw_aio_readv,
|
.bdrv_aio_readv = raw_aio_readv,
|
||||||
.bdrv_aio_writev = raw_aio_writev,
|
.bdrv_aio_writev = raw_aio_writev,
|
||||||
@@ -2276,6 +2316,9 @@ static BlockDriver bdrv_host_cdrom = {
|
|||||||
.bdrv_get_allocated_file_size
|
.bdrv_get_allocated_file_size
|
||||||
= raw_get_allocated_file_size,
|
= raw_get_allocated_file_size,
|
||||||
|
|
||||||
|
.bdrv_detach_aio_context = raw_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = raw_attach_aio_context,
|
||||||
|
|
||||||
/* removable device support */
|
/* removable device support */
|
||||||
.bdrv_is_inserted = cdrom_is_inserted,
|
.bdrv_is_inserted = cdrom_is_inserted,
|
||||||
.bdrv_eject = cdrom_eject,
|
.bdrv_eject = cdrom_eject,
|
||||||
@@ -2283,40 +2326,6 @@ static BlockDriver bdrv_host_cdrom = {
|
|||||||
};
|
};
|
||||||
#endif /* __FreeBSD__ */
|
#endif /* __FreeBSD__ */
|
||||||
|
|
||||||
#ifdef CONFIG_LINUX_AIO
|
|
||||||
/**
|
|
||||||
* Return the file descriptor for Linux AIO
|
|
||||||
*
|
|
||||||
* This function is a layering violation and should be removed when it becomes
|
|
||||||
* possible to call the block layer outside the global mutex. It allows the
|
|
||||||
* caller to hijack the file descriptor so I/O can be performed outside the
|
|
||||||
* block layer.
|
|
||||||
*/
|
|
||||||
int raw_get_aio_fd(BlockDriverState *bs)
|
|
||||||
{
|
|
||||||
BDRVRawState *s;
|
|
||||||
|
|
||||||
if (!bs->drv) {
|
|
||||||
return -ENOMEDIUM;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bs->drv == bdrv_find_format("raw")) {
|
|
||||||
bs = bs->file;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* raw-posix has several protocols so just check for raw_aio_readv */
|
|
||||||
if (bs->drv->bdrv_aio_readv != raw_aio_readv) {
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
s = bs->opaque;
|
|
||||||
if (!s->use_aio) {
|
|
||||||
return -ENOTSUP;
|
|
||||||
}
|
|
||||||
return s->fd;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_LINUX_AIO */
|
|
||||||
|
|
||||||
static void bdrv_file_init(void)
|
static void bdrv_file_init(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -36,8 +36,6 @@
|
|||||||
#define FTYPE_CD 1
|
#define FTYPE_CD 1
|
||||||
#define FTYPE_HARDDISK 2
|
#define FTYPE_HARDDISK 2
|
||||||
|
|
||||||
static QEMUWin32AIOState *aio;
|
|
||||||
|
|
||||||
typedef struct RawWin32AIOData {
|
typedef struct RawWin32AIOData {
|
||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
HANDLE hfile;
|
HANDLE hfile;
|
||||||
@@ -202,6 +200,25 @@ static int set_sparse(int fd)
|
|||||||
NULL, 0, NULL, 0, &returned, NULL);
|
NULL, 0, NULL, 0, &returned, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void raw_detach_aio_context(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
BDRVRawState *s = bs->opaque;
|
||||||
|
|
||||||
|
if (s->aio) {
|
||||||
|
win32_aio_detach_aio_context(s->aio, bdrv_get_aio_context(bs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void raw_attach_aio_context(BlockDriverState *bs,
|
||||||
|
AioContext *new_context)
|
||||||
|
{
|
||||||
|
BDRVRawState *s = bs->opaque;
|
||||||
|
|
||||||
|
if (s->aio) {
|
||||||
|
win32_aio_attach_aio_context(s->aio, new_context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void raw_probe_alignment(BlockDriverState *bs)
|
static void raw_probe_alignment(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVRawState *s = bs->opaque;
|
BDRVRawState *s = bs->opaque;
|
||||||
@@ -300,15 +317,6 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
|
|||||||
|
|
||||||
raw_parse_flags(flags, &access_flags, &overlapped);
|
raw_parse_flags(flags, &access_flags, &overlapped);
|
||||||
|
|
||||||
if ((flags & BDRV_O_NATIVE_AIO) && aio == NULL) {
|
|
||||||
aio = win32_aio_init();
|
|
||||||
if (aio == NULL) {
|
|
||||||
error_setg(errp, "Could not initialize AIO");
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filename[0] && filename[1] == ':') {
|
if (filename[0] && filename[1] == ':') {
|
||||||
snprintf(s->drive_path, sizeof(s->drive_path), "%c:\\", filename[0]);
|
snprintf(s->drive_path, sizeof(s->drive_path), "%c:\\", filename[0]);
|
||||||
} else if (filename[0] == '\\' && filename[1] == '\\') {
|
} else if (filename[0] == '\\' && filename[1] == '\\') {
|
||||||
@@ -335,13 +343,23 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (flags & BDRV_O_NATIVE_AIO) {
|
if (flags & BDRV_O_NATIVE_AIO) {
|
||||||
ret = win32_aio_attach(aio, s->hfile);
|
s->aio = win32_aio_init();
|
||||||
|
if (s->aio == NULL) {
|
||||||
|
CloseHandle(s->hfile);
|
||||||
|
error_setg(errp, "Could not initialize AIO");
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = win32_aio_attach(s->aio, s->hfile);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
win32_aio_cleanup(s->aio);
|
||||||
CloseHandle(s->hfile);
|
CloseHandle(s->hfile);
|
||||||
error_setg_errno(errp, -ret, "Could not enable AIO");
|
error_setg_errno(errp, -ret, "Could not enable AIO");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
s->aio = aio;
|
|
||||||
|
win32_aio_attach_aio_context(s->aio, bdrv_get_aio_context(bs));
|
||||||
}
|
}
|
||||||
|
|
||||||
raw_probe_alignment(bs);
|
raw_probe_alignment(bs);
|
||||||
@@ -389,6 +407,13 @@ static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs,
|
|||||||
static void raw_close(BlockDriverState *bs)
|
static void raw_close(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVRawState *s = bs->opaque;
|
BDRVRawState *s = bs->opaque;
|
||||||
|
|
||||||
|
if (s->aio) {
|
||||||
|
win32_aio_detach_aio_context(s->aio, bdrv_get_aio_context(bs));
|
||||||
|
win32_aio_cleanup(s->aio);
|
||||||
|
s->aio = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
CloseHandle(s->hfile);
|
CloseHandle(s->hfile);
|
||||||
if (bs->open_flags & BDRV_O_TEMPORARY) {
|
if (bs->open_flags & BDRV_O_TEMPORARY) {
|
||||||
unlink(bs->filename);
|
unlink(bs->filename);
|
||||||
@@ -478,8 +503,7 @@ static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
|
|||||||
return st.st_size;
|
return st.st_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int raw_create(const char *filename, QEMUOptionParameter *options,
|
static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
int64_t total_size = 0;
|
int64_t total_size = 0;
|
||||||
@@ -487,12 +511,8 @@ static int raw_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
strstart(filename, "file:", &filename);
|
strstart(filename, "file:", &filename);
|
||||||
|
|
||||||
/* Read out options */
|
/* Read out options */
|
||||||
while (options && options->name) {
|
total_size =
|
||||||
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
|
qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
|
||||||
total_size = options->value.n / 512;
|
|
||||||
}
|
|
||||||
options++;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
|
fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
|
||||||
0644);
|
0644);
|
||||||
@@ -506,13 +526,18 @@ static int raw_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QEMUOptionParameter raw_create_options[] = {
|
|
||||||
{
|
static QemuOptsList raw_create_opts = {
|
||||||
.name = BLOCK_OPT_SIZE,
|
.name = "raw-create-opts",
|
||||||
.type = OPT_SIZE,
|
.head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head),
|
||||||
.help = "Virtual disk size"
|
.desc = {
|
||||||
},
|
{
|
||||||
{ NULL }
|
.name = BLOCK_OPT_SIZE,
|
||||||
|
.type = QEMU_OPT_SIZE,
|
||||||
|
.help = "Virtual disk size"
|
||||||
|
},
|
||||||
|
{ /* end of list */ }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_file = {
|
static BlockDriver bdrv_file = {
|
||||||
@@ -521,9 +546,9 @@ static BlockDriver bdrv_file = {
|
|||||||
.instance_size = sizeof(BDRVRawState),
|
.instance_size = sizeof(BDRVRawState),
|
||||||
.bdrv_needs_filename = true,
|
.bdrv_needs_filename = true,
|
||||||
.bdrv_parse_filename = raw_parse_filename,
|
.bdrv_parse_filename = raw_parse_filename,
|
||||||
.bdrv_file_open = raw_open,
|
.bdrv_file_open = raw_open,
|
||||||
.bdrv_close = raw_close,
|
.bdrv_close = raw_close,
|
||||||
.bdrv_create = raw_create,
|
.bdrv_create = raw_create,
|
||||||
.bdrv_has_zero_init = bdrv_has_zero_init_1,
|
.bdrv_has_zero_init = bdrv_has_zero_init_1,
|
||||||
|
|
||||||
.bdrv_aio_readv = raw_aio_readv,
|
.bdrv_aio_readv = raw_aio_readv,
|
||||||
@@ -535,7 +560,7 @@ static BlockDriver bdrv_file = {
|
|||||||
.bdrv_get_allocated_file_size
|
.bdrv_get_allocated_file_size
|
||||||
= raw_get_allocated_file_size,
|
= raw_get_allocated_file_size,
|
||||||
|
|
||||||
.create_options = raw_create_options,
|
.create_opts = &raw_create_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
/***********************************************/
|
/***********************************************/
|
||||||
@@ -684,6 +709,9 @@ static BlockDriver bdrv_host_device = {
|
|||||||
.bdrv_aio_writev = raw_aio_writev,
|
.bdrv_aio_writev = raw_aio_writev,
|
||||||
.bdrv_aio_flush = raw_aio_flush,
|
.bdrv_aio_flush = raw_aio_flush,
|
||||||
|
|
||||||
|
.bdrv_detach_aio_context = raw_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = raw_attach_aio_context,
|
||||||
|
|
||||||
.bdrv_getlength = raw_getlength,
|
.bdrv_getlength = raw_getlength,
|
||||||
.has_variable_length = true,
|
.has_variable_length = true,
|
||||||
|
|
||||||
|
|||||||
@@ -29,13 +29,17 @@
|
|||||||
#include "block/block_int.h"
|
#include "block/block_int.h"
|
||||||
#include "qemu/option.h"
|
#include "qemu/option.h"
|
||||||
|
|
||||||
static QEMUOptionParameter raw_create_options[] = {
|
static QemuOptsList raw_create_opts = {
|
||||||
{
|
.name = "raw-create-opts",
|
||||||
.name = BLOCK_OPT_SIZE,
|
.head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head),
|
||||||
.type = OPT_SIZE,
|
.desc = {
|
||||||
.help = "Virtual disk size"
|
{
|
||||||
},
|
.name = BLOCK_OPT_SIZE,
|
||||||
{ 0 }
|
.type = QEMU_OPT_SIZE,
|
||||||
|
.help = "Virtual disk size"
|
||||||
|
},
|
||||||
|
{ /* end of list */ }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int raw_reopen_prepare(BDRVReopenState *reopen_state,
|
static int raw_reopen_prepare(BDRVReopenState *reopen_state,
|
||||||
@@ -139,13 +143,12 @@ static int raw_has_zero_init(BlockDriverState *bs)
|
|||||||
return bdrv_has_zero_init(bs->file);
|
return bdrv_has_zero_init(bs->file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int raw_create(const char *filename, QEMUOptionParameter *options,
|
static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = bdrv_create_file(filename, options, &local_err);
|
ret = bdrv_create_file(filename, opts, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
}
|
}
|
||||||
@@ -194,7 +197,7 @@ static BlockDriver bdrv_raw = {
|
|||||||
.bdrv_lock_medium = &raw_lock_medium,
|
.bdrv_lock_medium = &raw_lock_medium,
|
||||||
.bdrv_ioctl = &raw_ioctl,
|
.bdrv_ioctl = &raw_ioctl,
|
||||||
.bdrv_aio_ioctl = &raw_aio_ioctl,
|
.bdrv_aio_ioctl = &raw_aio_ioctl,
|
||||||
.create_options = &raw_create_options[0],
|
.create_opts = &raw_create_opts,
|
||||||
.bdrv_has_zero_init = &raw_has_zero_init
|
.bdrv_has_zero_init = &raw_has_zero_init
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
71
block/rbd.c
71
block/rbd.c
@@ -289,8 +289,7 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf, Error **errp)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options,
|
static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
int64_t bytes = 0;
|
int64_t bytes = 0;
|
||||||
@@ -315,24 +314,18 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Read out options */
|
/* Read out options */
|
||||||
while (options && options->name) {
|
bytes = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
|
||||||
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
|
objsize = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE, 0);
|
||||||
bytes = options->value.n;
|
if (objsize) {
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
|
if ((objsize - 1) & objsize) { /* not a power of 2? */
|
||||||
if (options->value.n) {
|
error_setg(errp, "obj size needs to be power of 2");
|
||||||
objsize = options->value.n;
|
return -EINVAL;
|
||||||
if ((objsize - 1) & objsize) { /* not a power of 2? */
|
|
||||||
error_setg(errp, "obj size needs to be power of 2");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (objsize < 4096) {
|
|
||||||
error_setg(errp, "obj size too small");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
obj_order = ffs(objsize) - 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
options++;
|
if (objsize < 4096) {
|
||||||
|
error_setg(errp, "obj size too small");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
obj_order = ffs(objsize) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
clientname = qemu_rbd_parse_clientname(conf, clientname_buf);
|
clientname = qemu_rbd_parse_clientname(conf, clientname_buf);
|
||||||
@@ -555,7 +548,7 @@ static void qemu_rbd_aio_cancel(BlockDriverAIOCB *blockacb)
|
|||||||
acb->cancelled = 1;
|
acb->cancelled = 1;
|
||||||
|
|
||||||
while (acb->status == -EINPROGRESS) {
|
while (acb->status == -EINPROGRESS) {
|
||||||
qemu_aio_wait();
|
aio_poll(bdrv_get_aio_context(acb->common.bs), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_aio_release(acb);
|
qemu_aio_release(acb);
|
||||||
@@ -588,7 +581,8 @@ static void rbd_finish_aiocb(rbd_completion_t c, RADOSCB *rcb)
|
|||||||
rcb->ret = rbd_aio_get_return_value(c);
|
rcb->ret = rbd_aio_get_return_value(c);
|
||||||
rbd_aio_release(c);
|
rbd_aio_release(c);
|
||||||
|
|
||||||
acb->bh = qemu_bh_new(rbd_finish_bh, rcb);
|
acb->bh = aio_bh_new(bdrv_get_aio_context(acb->common.bs),
|
||||||
|
rbd_finish_bh, rcb);
|
||||||
qemu_bh_schedule(acb->bh);
|
qemu_bh_schedule(acb->bh);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -684,13 +678,16 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
goto failed;
|
goto failed_completion;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &acb->common;
|
return &acb->common;
|
||||||
|
|
||||||
|
failed_completion:
|
||||||
|
rbd_aio_release(c);
|
||||||
failed:
|
failed:
|
||||||
g_free(rcb);
|
g_free(rcb);
|
||||||
|
qemu_vfree(acb->bounce);
|
||||||
qemu_aio_release(acb);
|
qemu_aio_release(acb);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -907,18 +904,22 @@ static BlockDriverAIOCB* qemu_rbd_aio_discard(BlockDriverState *bs,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static QEMUOptionParameter qemu_rbd_create_options[] = {
|
static QemuOptsList qemu_rbd_create_opts = {
|
||||||
{
|
.name = "rbd-create-opts",
|
||||||
.name = BLOCK_OPT_SIZE,
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_rbd_create_opts.head),
|
||||||
.type = OPT_SIZE,
|
.desc = {
|
||||||
.help = "Virtual disk size"
|
{
|
||||||
},
|
.name = BLOCK_OPT_SIZE,
|
||||||
{
|
.type = QEMU_OPT_SIZE,
|
||||||
.name = BLOCK_OPT_CLUSTER_SIZE,
|
.help = "Virtual disk size"
|
||||||
.type = OPT_SIZE,
|
},
|
||||||
.help = "RBD object size"
|
{
|
||||||
},
|
.name = BLOCK_OPT_CLUSTER_SIZE,
|
||||||
{NULL}
|
.type = QEMU_OPT_SIZE,
|
||||||
|
.help = "RBD object size"
|
||||||
|
},
|
||||||
|
{ /* end of list */ }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_rbd = {
|
static BlockDriver bdrv_rbd = {
|
||||||
@@ -930,7 +931,7 @@ static BlockDriver bdrv_rbd = {
|
|||||||
.bdrv_create = qemu_rbd_create,
|
.bdrv_create = qemu_rbd_create,
|
||||||
.bdrv_has_zero_init = bdrv_has_zero_init_1,
|
.bdrv_has_zero_init = bdrv_has_zero_init_1,
|
||||||
.bdrv_get_info = qemu_rbd_getinfo,
|
.bdrv_get_info = qemu_rbd_getinfo,
|
||||||
.create_options = qemu_rbd_create_options,
|
.create_opts = &qemu_rbd_create_opts,
|
||||||
.bdrv_getlength = qemu_rbd_getlength,
|
.bdrv_getlength = qemu_rbd_getlength,
|
||||||
.bdrv_truncate = qemu_rbd_truncate,
|
.bdrv_truncate = qemu_rbd_truncate,
|
||||||
.protocol_name = "rbd",
|
.protocol_name = "rbd",
|
||||||
|
|||||||
272
block/sheepdog.c
272
block/sheepdog.c
@@ -200,6 +200,8 @@ typedef struct SheepdogInode {
|
|||||||
uint32_t data_vdi_id[MAX_DATA_OBJS];
|
uint32_t data_vdi_id[MAX_DATA_OBJS];
|
||||||
} SheepdogInode;
|
} SheepdogInode;
|
||||||
|
|
||||||
|
#define SD_INODE_HEADER_SIZE offsetof(SheepdogInode, data_vdi_id)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 64 bit FNV-1a non-zero initial basis
|
* 64 bit FNV-1a non-zero initial basis
|
||||||
*/
|
*/
|
||||||
@@ -282,6 +284,7 @@ typedef struct AIOReq {
|
|||||||
unsigned int data_len;
|
unsigned int data_len;
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
bool create;
|
||||||
|
|
||||||
QLIST_ENTRY(AIOReq) aio_siblings;
|
QLIST_ENTRY(AIOReq) aio_siblings;
|
||||||
} AIOReq;
|
} AIOReq;
|
||||||
@@ -314,6 +317,7 @@ struct SheepdogAIOCB {
|
|||||||
|
|
||||||
typedef struct BDRVSheepdogState {
|
typedef struct BDRVSheepdogState {
|
||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
|
AioContext *aio_context;
|
||||||
|
|
||||||
SheepdogInode inode;
|
SheepdogInode inode;
|
||||||
|
|
||||||
@@ -404,7 +408,7 @@ static const char * sd_strerror(int err)
|
|||||||
|
|
||||||
static inline AIOReq *alloc_aio_req(BDRVSheepdogState *s, SheepdogAIOCB *acb,
|
static inline AIOReq *alloc_aio_req(BDRVSheepdogState *s, SheepdogAIOCB *acb,
|
||||||
uint64_t oid, unsigned int data_len,
|
uint64_t oid, unsigned int data_len,
|
||||||
uint64_t offset, uint8_t flags,
|
uint64_t offset, uint8_t flags, bool create,
|
||||||
uint64_t base_oid, unsigned int iov_offset)
|
uint64_t base_oid, unsigned int iov_offset)
|
||||||
{
|
{
|
||||||
AIOReq *aio_req;
|
AIOReq *aio_req;
|
||||||
@@ -418,6 +422,7 @@ static inline AIOReq *alloc_aio_req(BDRVSheepdogState *s, SheepdogAIOCB *acb,
|
|||||||
aio_req->data_len = data_len;
|
aio_req->data_len = data_len;
|
||||||
aio_req->flags = flags;
|
aio_req->flags = flags;
|
||||||
aio_req->id = s->aioreq_seq_num++;
|
aio_req->id = s->aioreq_seq_num++;
|
||||||
|
aio_req->create = create;
|
||||||
|
|
||||||
acb->nr_pending++;
|
acb->nr_pending++;
|
||||||
return aio_req;
|
return aio_req;
|
||||||
@@ -496,7 +501,7 @@ static void sd_aio_cancel(BlockDriverAIOCB *blockacb)
|
|||||||
sd_finish_aiocb(acb);
|
sd_finish_aiocb(acb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qemu_aio_wait();
|
aio_poll(s->aio_context, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -578,6 +583,7 @@ static void restart_co_req(void *opaque)
|
|||||||
|
|
||||||
typedef struct SheepdogReqCo {
|
typedef struct SheepdogReqCo {
|
||||||
int sockfd;
|
int sockfd;
|
||||||
|
AioContext *aio_context;
|
||||||
SheepdogReq *hdr;
|
SheepdogReq *hdr;
|
||||||
void *data;
|
void *data;
|
||||||
unsigned int *wlen;
|
unsigned int *wlen;
|
||||||
@@ -598,14 +604,14 @@ static coroutine_fn void do_co_req(void *opaque)
|
|||||||
unsigned int *rlen = srco->rlen;
|
unsigned int *rlen = srco->rlen;
|
||||||
|
|
||||||
co = qemu_coroutine_self();
|
co = qemu_coroutine_self();
|
||||||
qemu_aio_set_fd_handler(sockfd, NULL, restart_co_req, co);
|
aio_set_fd_handler(srco->aio_context, sockfd, NULL, restart_co_req, co);
|
||||||
|
|
||||||
ret = send_co_req(sockfd, hdr, data, wlen);
|
ret = send_co_req(sockfd, hdr, data, wlen);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_aio_set_fd_handler(sockfd, restart_co_req, NULL, co);
|
aio_set_fd_handler(srco->aio_context, sockfd, restart_co_req, NULL, co);
|
||||||
|
|
||||||
ret = qemu_co_recv(sockfd, hdr, sizeof(*hdr));
|
ret = qemu_co_recv(sockfd, hdr, sizeof(*hdr));
|
||||||
if (ret != sizeof(*hdr)) {
|
if (ret != sizeof(*hdr)) {
|
||||||
@@ -630,18 +636,19 @@ static coroutine_fn void do_co_req(void *opaque)
|
|||||||
out:
|
out:
|
||||||
/* there is at most one request for this sockfd, so it is safe to
|
/* there is at most one request for this sockfd, so it is safe to
|
||||||
* set each handler to NULL. */
|
* set each handler to NULL. */
|
||||||
qemu_aio_set_fd_handler(sockfd, NULL, NULL, NULL);
|
aio_set_fd_handler(srco->aio_context, sockfd, NULL, NULL, NULL);
|
||||||
|
|
||||||
srco->ret = ret;
|
srco->ret = ret;
|
||||||
srco->finished = true;
|
srco->finished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_req(int sockfd, SheepdogReq *hdr, void *data,
|
static int do_req(int sockfd, AioContext *aio_context, SheepdogReq *hdr,
|
||||||
unsigned int *wlen, unsigned int *rlen)
|
void *data, unsigned int *wlen, unsigned int *rlen)
|
||||||
{
|
{
|
||||||
Coroutine *co;
|
Coroutine *co;
|
||||||
SheepdogReqCo srco = {
|
SheepdogReqCo srco = {
|
||||||
.sockfd = sockfd,
|
.sockfd = sockfd,
|
||||||
|
.aio_context = aio_context,
|
||||||
.hdr = hdr,
|
.hdr = hdr,
|
||||||
.data = data,
|
.data = data,
|
||||||
.wlen = wlen,
|
.wlen = wlen,
|
||||||
@@ -656,7 +663,7 @@ static int do_req(int sockfd, SheepdogReq *hdr, void *data,
|
|||||||
co = qemu_coroutine_create(do_co_req);
|
co = qemu_coroutine_create(do_co_req);
|
||||||
qemu_coroutine_enter(co, &srco);
|
qemu_coroutine_enter(co, &srco);
|
||||||
while (!srco.finished) {
|
while (!srco.finished) {
|
||||||
qemu_aio_wait();
|
aio_poll(aio_context, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -664,8 +671,8 @@ static int do_req(int sockfd, SheepdogReq *hdr, void *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
|
static void coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
|
||||||
struct iovec *iov, int niov, bool create,
|
struct iovec *iov, int niov,
|
||||||
enum AIOCBState aiocb_type);
|
enum AIOCBState aiocb_type);
|
||||||
static void coroutine_fn resend_aioreq(BDRVSheepdogState *s, AIOReq *aio_req);
|
static void coroutine_fn resend_aioreq(BDRVSheepdogState *s, AIOReq *aio_req);
|
||||||
static int reload_inode(BDRVSheepdogState *s, uint32_t snapid, const char *tag);
|
static int reload_inode(BDRVSheepdogState *s, uint32_t snapid, const char *tag);
|
||||||
static int get_sheep_fd(BDRVSheepdogState *s, Error **errp);
|
static int get_sheep_fd(BDRVSheepdogState *s, Error **errp);
|
||||||
@@ -698,7 +705,7 @@ static void coroutine_fn send_pending_req(BDRVSheepdogState *s, uint64_t oid)
|
|||||||
/* move aio_req from pending list to inflight one */
|
/* move aio_req from pending list to inflight one */
|
||||||
QLIST_REMOVE(aio_req, aio_siblings);
|
QLIST_REMOVE(aio_req, aio_siblings);
|
||||||
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
|
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
|
||||||
add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov, false,
|
add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov,
|
||||||
acb->aiocb_type);
|
acb->aiocb_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -709,7 +716,7 @@ static coroutine_fn void reconnect_to_sdog(void *opaque)
|
|||||||
BDRVSheepdogState *s = opaque;
|
BDRVSheepdogState *s = opaque;
|
||||||
AIOReq *aio_req, *next;
|
AIOReq *aio_req, *next;
|
||||||
|
|
||||||
qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL);
|
aio_set_fd_handler(s->aio_context, s->fd, NULL, NULL, NULL);
|
||||||
close(s->fd);
|
close(s->fd);
|
||||||
s->fd = -1;
|
s->fd = -1;
|
||||||
|
|
||||||
@@ -797,7 +804,7 @@ static void coroutine_fn aio_read_response(void *opaque)
|
|||||||
}
|
}
|
||||||
idx = data_oid_to_idx(aio_req->oid);
|
idx = data_oid_to_idx(aio_req->oid);
|
||||||
|
|
||||||
if (s->inode.data_vdi_id[idx] != s->inode.vdi_id) {
|
if (aio_req->create) {
|
||||||
/*
|
/*
|
||||||
* If the object is newly created one, we need to update
|
* If the object is newly created one, we need to update
|
||||||
* the vdi object (metadata object). min_dirty_data_idx
|
* the vdi object (metadata object). min_dirty_data_idx
|
||||||
@@ -922,7 +929,7 @@ static int get_sheep_fd(BDRVSheepdogState *s, Error **errp)
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_aio_set_fd_handler(fd, co_read_response, NULL, s);
|
aio_set_fd_handler(s->aio_context, fd, co_read_response, NULL, s);
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1092,7 +1099,7 @@ static int find_vdi_name(BDRVSheepdogState *s, const char *filename,
|
|||||||
hdr.snapid = snapid;
|
hdr.snapid = snapid;
|
||||||
hdr.flags = SD_FLAG_CMD_WRITE;
|
hdr.flags = SD_FLAG_CMD_WRITE;
|
||||||
|
|
||||||
ret = do_req(fd, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
|
ret = do_req(fd, s->aio_context, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
error_setg_errno(errp, -ret, "cannot get vdi info");
|
error_setg_errno(errp, -ret, "cannot get vdi info");
|
||||||
goto out;
|
goto out;
|
||||||
@@ -1117,8 +1124,8 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
|
static void coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
|
||||||
struct iovec *iov, int niov, bool create,
|
struct iovec *iov, int niov,
|
||||||
enum AIOCBState aiocb_type)
|
enum AIOCBState aiocb_type)
|
||||||
{
|
{
|
||||||
int nr_copies = s->inode.nr_copies;
|
int nr_copies = s->inode.nr_copies;
|
||||||
SheepdogObjReq hdr;
|
SheepdogObjReq hdr;
|
||||||
@@ -1129,6 +1136,7 @@ static void coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
|
|||||||
uint64_t offset = aio_req->offset;
|
uint64_t offset = aio_req->offset;
|
||||||
uint8_t flags = aio_req->flags;
|
uint8_t flags = aio_req->flags;
|
||||||
uint64_t old_oid = aio_req->base_oid;
|
uint64_t old_oid = aio_req->base_oid;
|
||||||
|
bool create = aio_req->create;
|
||||||
|
|
||||||
if (!nr_copies) {
|
if (!nr_copies) {
|
||||||
error_report("bug");
|
error_report("bug");
|
||||||
@@ -1173,7 +1181,8 @@ static void coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
|
|||||||
|
|
||||||
qemu_co_mutex_lock(&s->lock);
|
qemu_co_mutex_lock(&s->lock);
|
||||||
s->co_send = qemu_coroutine_self();
|
s->co_send = qemu_coroutine_self();
|
||||||
qemu_aio_set_fd_handler(s->fd, co_read_response, co_write_request, s);
|
aio_set_fd_handler(s->aio_context, s->fd,
|
||||||
|
co_read_response, co_write_request, s);
|
||||||
socket_set_cork(s->fd, 1);
|
socket_set_cork(s->fd, 1);
|
||||||
|
|
||||||
/* send a header */
|
/* send a header */
|
||||||
@@ -1191,12 +1200,13 @@ static void coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
|
|||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
socket_set_cork(s->fd, 0);
|
socket_set_cork(s->fd, 0);
|
||||||
qemu_aio_set_fd_handler(s->fd, co_read_response, NULL, s);
|
aio_set_fd_handler(s->aio_context, s->fd, co_read_response, NULL, s);
|
||||||
s->co_send = NULL;
|
s->co_send = NULL;
|
||||||
qemu_co_mutex_unlock(&s->lock);
|
qemu_co_mutex_unlock(&s->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_write_object(int fd, char *buf, uint64_t oid, uint8_t copies,
|
static int read_write_object(int fd, AioContext *aio_context, char *buf,
|
||||||
|
uint64_t oid, uint8_t copies,
|
||||||
unsigned int datalen, uint64_t offset,
|
unsigned int datalen, uint64_t offset,
|
||||||
bool write, bool create, uint32_t cache_flags)
|
bool write, bool create, uint32_t cache_flags)
|
||||||
{
|
{
|
||||||
@@ -1229,7 +1239,7 @@ static int read_write_object(int fd, char *buf, uint64_t oid, uint8_t copies,
|
|||||||
hdr.offset = offset;
|
hdr.offset = offset;
|
||||||
hdr.copies = copies;
|
hdr.copies = copies;
|
||||||
|
|
||||||
ret = do_req(fd, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
|
ret = do_req(fd, aio_context, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
error_report("failed to send a request to the sheep");
|
error_report("failed to send a request to the sheep");
|
||||||
return ret;
|
return ret;
|
||||||
@@ -1244,19 +1254,23 @@ static int read_write_object(int fd, char *buf, uint64_t oid, uint8_t copies,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_object(int fd, char *buf, uint64_t oid, uint8_t copies,
|
static int read_object(int fd, AioContext *aio_context, char *buf,
|
||||||
|
uint64_t oid, uint8_t copies,
|
||||||
unsigned int datalen, uint64_t offset,
|
unsigned int datalen, uint64_t offset,
|
||||||
uint32_t cache_flags)
|
uint32_t cache_flags)
|
||||||
{
|
{
|
||||||
return read_write_object(fd, buf, oid, copies, datalen, offset, false,
|
return read_write_object(fd, aio_context, buf, oid, copies,
|
||||||
|
datalen, offset, false,
|
||||||
false, cache_flags);
|
false, cache_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_object(int fd, char *buf, uint64_t oid, uint8_t copies,
|
static int write_object(int fd, AioContext *aio_context, char *buf,
|
||||||
|
uint64_t oid, uint8_t copies,
|
||||||
unsigned int datalen, uint64_t offset, bool create,
|
unsigned int datalen, uint64_t offset, bool create,
|
||||||
uint32_t cache_flags)
|
uint32_t cache_flags)
|
||||||
{
|
{
|
||||||
return read_write_object(fd, buf, oid, copies, datalen, offset, true,
|
return read_write_object(fd, aio_context, buf, oid, copies,
|
||||||
|
datalen, offset, true,
|
||||||
create, cache_flags);
|
create, cache_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1275,7 +1289,7 @@ static int reload_inode(BDRVSheepdogState *s, uint32_t snapid, const char *tag)
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
inode = g_malloc(sizeof(s->inode));
|
inode = g_malloc(SD_INODE_HEADER_SIZE);
|
||||||
|
|
||||||
ret = find_vdi_name(s, s->name, snapid, tag, &vid, false, &local_err);
|
ret = find_vdi_name(s, s->name, snapid, tag, &vid, false, &local_err);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -1284,14 +1298,15 @@ static int reload_inode(BDRVSheepdogState *s, uint32_t snapid, const char *tag)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = read_object(fd, (char *)inode, vid_to_vdi_oid(vid),
|
ret = read_object(fd, s->aio_context, (char *)inode, vid_to_vdi_oid(vid),
|
||||||
s->inode.nr_copies, sizeof(*inode), 0, s->cache_flags);
|
s->inode.nr_copies, SD_INODE_HEADER_SIZE, 0,
|
||||||
|
s->cache_flags);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inode->vdi_id != s->inode.vdi_id) {
|
if (inode->vdi_id != s->inode.vdi_id) {
|
||||||
memcpy(&s->inode, inode, sizeof(s->inode));
|
memcpy(&s->inode, inode, SD_INODE_HEADER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -1315,6 +1330,7 @@ static bool check_simultaneous_create(BDRVSheepdogState *s, AIOReq *aio_req)
|
|||||||
DPRINTF("simultaneous create to %" PRIx64 "\n", aio_req->oid);
|
DPRINTF("simultaneous create to %" PRIx64 "\n", aio_req->oid);
|
||||||
aio_req->flags = 0;
|
aio_req->flags = 0;
|
||||||
aio_req->base_oid = 0;
|
aio_req->base_oid = 0;
|
||||||
|
aio_req->create = false;
|
||||||
QLIST_REMOVE(aio_req, aio_siblings);
|
QLIST_REMOVE(aio_req, aio_siblings);
|
||||||
QLIST_INSERT_HEAD(&s->pending_aio_head, aio_req, aio_siblings);
|
QLIST_INSERT_HEAD(&s->pending_aio_head, aio_req, aio_siblings);
|
||||||
return true;
|
return true;
|
||||||
@@ -1327,7 +1343,8 @@ static bool check_simultaneous_create(BDRVSheepdogState *s, AIOReq *aio_req)
|
|||||||
static void coroutine_fn resend_aioreq(BDRVSheepdogState *s, AIOReq *aio_req)
|
static void coroutine_fn resend_aioreq(BDRVSheepdogState *s, AIOReq *aio_req)
|
||||||
{
|
{
|
||||||
SheepdogAIOCB *acb = aio_req->aiocb;
|
SheepdogAIOCB *acb = aio_req->aiocb;
|
||||||
bool create = false;
|
|
||||||
|
aio_req->create = false;
|
||||||
|
|
||||||
/* check whether this request becomes a CoW one */
|
/* check whether this request becomes a CoW one */
|
||||||
if (acb->aiocb_type == AIOCB_WRITE_UDATA && is_data_obj(aio_req->oid)) {
|
if (acb->aiocb_type == AIOCB_WRITE_UDATA && is_data_obj(aio_req->oid)) {
|
||||||
@@ -1345,20 +1362,36 @@ static void coroutine_fn resend_aioreq(BDRVSheepdogState *s, AIOReq *aio_req)
|
|||||||
aio_req->base_oid = vid_to_data_oid(s->inode.data_vdi_id[idx], idx);
|
aio_req->base_oid = vid_to_data_oid(s->inode.data_vdi_id[idx], idx);
|
||||||
aio_req->flags |= SD_FLAG_CMD_COW;
|
aio_req->flags |= SD_FLAG_CMD_COW;
|
||||||
}
|
}
|
||||||
create = true;
|
aio_req->create = true;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
if (is_data_obj(aio_req->oid)) {
|
if (is_data_obj(aio_req->oid)) {
|
||||||
add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov, create,
|
add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov,
|
||||||
acb->aiocb_type);
|
acb->aiocb_type);
|
||||||
} else {
|
} else {
|
||||||
struct iovec iov;
|
struct iovec iov;
|
||||||
iov.iov_base = &s->inode;
|
iov.iov_base = &s->inode;
|
||||||
iov.iov_len = sizeof(s->inode);
|
iov.iov_len = sizeof(s->inode);
|
||||||
add_aio_request(s, aio_req, &iov, 1, false, AIOCB_WRITE_UDATA);
|
add_aio_request(s, aio_req, &iov, 1, AIOCB_WRITE_UDATA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sd_detach_aio_context(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
BDRVSheepdogState *s = bs->opaque;
|
||||||
|
|
||||||
|
aio_set_fd_handler(s->aio_context, s->fd, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sd_attach_aio_context(BlockDriverState *bs,
|
||||||
|
AioContext *new_context)
|
||||||
|
{
|
||||||
|
BDRVSheepdogState *s = bs->opaque;
|
||||||
|
|
||||||
|
s->aio_context = new_context;
|
||||||
|
aio_set_fd_handler(new_context, s->fd, co_read_response, NULL, s);
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO Convert to fine grained options */
|
/* TODO Convert to fine grained options */
|
||||||
static QemuOptsList runtime_opts = {
|
static QemuOptsList runtime_opts = {
|
||||||
.name = "sheepdog",
|
.name = "sheepdog",
|
||||||
@@ -1387,6 +1420,7 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags,
|
|||||||
const char *filename;
|
const char *filename;
|
||||||
|
|
||||||
s->bs = bs;
|
s->bs = bs;
|
||||||
|
s->aio_context = bdrv_get_aio_context(bs);
|
||||||
|
|
||||||
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
|
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
|
||||||
qemu_opts_absorb_qdict(opts, options, &local_err);
|
qemu_opts_absorb_qdict(opts, options, &local_err);
|
||||||
@@ -1448,8 +1482,8 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags,
|
|||||||
}
|
}
|
||||||
|
|
||||||
buf = g_malloc(SD_INODE_SIZE);
|
buf = g_malloc(SD_INODE_SIZE);
|
||||||
ret = read_object(fd, buf, vid_to_vdi_oid(vid), 0, SD_INODE_SIZE, 0,
|
ret = read_object(fd, s->aio_context, buf, vid_to_vdi_oid(vid),
|
||||||
s->cache_flags);
|
0, SD_INODE_SIZE, 0, s->cache_flags);
|
||||||
|
|
||||||
closesocket(fd);
|
closesocket(fd);
|
||||||
|
|
||||||
@@ -1469,7 +1503,7 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags,
|
|||||||
g_free(buf);
|
g_free(buf);
|
||||||
return 0;
|
return 0;
|
||||||
out:
|
out:
|
||||||
qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL);
|
aio_set_fd_handler(bdrv_get_aio_context(bs), s->fd, NULL, NULL, NULL);
|
||||||
if (s->fd >= 0) {
|
if (s->fd >= 0) {
|
||||||
closesocket(s->fd);
|
closesocket(s->fd);
|
||||||
}
|
}
|
||||||
@@ -1512,7 +1546,7 @@ static int do_sd_create(BDRVSheepdogState *s, uint32_t *vdi_id, int snapshot,
|
|||||||
hdr.copy_policy = s->inode.copy_policy;
|
hdr.copy_policy = s->inode.copy_policy;
|
||||||
hdr.copies = s->inode.nr_copies;
|
hdr.copies = s->inode.nr_copies;
|
||||||
|
|
||||||
ret = do_req(fd, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
|
ret = do_req(fd, s->aio_context, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
|
||||||
|
|
||||||
closesocket(fd);
|
closesocket(fd);
|
||||||
|
|
||||||
@@ -1636,12 +1670,13 @@ static int parse_redundancy(BDRVSheepdogState *s, const char *opt)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sd_create(const char *filename, QEMUOptionParameter *options,
|
static int sd_create(const char *filename, QemuOpts *opts,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
uint32_t vid = 0;
|
uint32_t vid = 0;
|
||||||
char *backing_file = NULL;
|
char *backing_file = NULL;
|
||||||
|
char *buf = NULL;
|
||||||
BDRVSheepdogState *s;
|
BDRVSheepdogState *s;
|
||||||
char tag[SD_MAX_VDI_TAG_LEN];
|
char tag[SD_MAX_VDI_TAG_LEN];
|
||||||
uint32_t snapid;
|
uint32_t snapid;
|
||||||
@@ -1660,33 +1695,27 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (options && options->name) {
|
s->inode.vdi_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
|
||||||
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
|
backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
|
||||||
s->inode.vdi_size = options->value.n;
|
buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
|
if (!buf || !strcmp(buf, "off")) {
|
||||||
backing_file = options->value.s;
|
prealloc = false;
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
|
} else if (!strcmp(buf, "full")) {
|
||||||
if (!options->value.s || !strcmp(options->value.s, "off")) {
|
prealloc = true;
|
||||||
prealloc = false;
|
} else {
|
||||||
} else if (!strcmp(options->value.s, "full")) {
|
error_setg(errp, "Invalid preallocation mode: '%s'", buf);
|
||||||
prealloc = true;
|
ret = -EINVAL;
|
||||||
} else {
|
goto out;
|
||||||
error_setg(errp, "Invalid preallocation mode: '%s'",
|
}
|
||||||
options->value.s);
|
|
||||||
ret = -EINVAL;
|
g_free(buf);
|
||||||
goto out;
|
buf = qemu_opt_get_del(opts, BLOCK_OPT_REDUNDANCY);
|
||||||
}
|
if (buf) {
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_REDUNDANCY)) {
|
ret = parse_redundancy(s, buf);
|
||||||
if (options->value.s) {
|
if (ret < 0) {
|
||||||
ret = parse_redundancy(s, options->value.s);
|
error_setg(errp, "Invalid redundancy mode: '%s'", buf);
|
||||||
if (ret < 0) {
|
goto out;
|
||||||
error_setg(errp, "Invalid redundancy mode: '%s'",
|
|
||||||
options->value.s);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
options++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->inode.vdi_size > SD_MAX_VDI_SIZE) {
|
if (s->inode.vdi_size > SD_MAX_VDI_SIZE) {
|
||||||
@@ -1736,6 +1765,8 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
ret = sd_prealloc(filename, errp);
|
ret = sd_prealloc(filename, errp);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
g_free(backing_file);
|
||||||
|
g_free(buf);
|
||||||
g_free(s);
|
g_free(s);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -1766,7 +1797,8 @@ static void sd_close(BlockDriverState *bs)
|
|||||||
hdr.data_length = wlen;
|
hdr.data_length = wlen;
|
||||||
hdr.flags = SD_FLAG_CMD_WRITE;
|
hdr.flags = SD_FLAG_CMD_WRITE;
|
||||||
|
|
||||||
ret = do_req(fd, (SheepdogReq *)&hdr, s->name, &wlen, &rlen);
|
ret = do_req(fd, s->aio_context, (SheepdogReq *)&hdr,
|
||||||
|
s->name, &wlen, &rlen);
|
||||||
|
|
||||||
closesocket(fd);
|
closesocket(fd);
|
||||||
|
|
||||||
@@ -1775,7 +1807,7 @@ static void sd_close(BlockDriverState *bs)
|
|||||||
error_report("%s, %s", sd_strerror(rsp->result), s->name);
|
error_report("%s, %s", sd_strerror(rsp->result), s->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL);
|
aio_set_fd_handler(bdrv_get_aio_context(bs), s->fd, NULL, NULL, NULL);
|
||||||
closesocket(s->fd);
|
closesocket(s->fd);
|
||||||
g_free(s->host_spec);
|
g_free(s->host_spec);
|
||||||
}
|
}
|
||||||
@@ -1812,8 +1844,9 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset)
|
|||||||
/* we don't need to update entire object */
|
/* we don't need to update entire object */
|
||||||
datalen = SD_INODE_SIZE - sizeof(s->inode.data_vdi_id);
|
datalen = SD_INODE_SIZE - sizeof(s->inode.data_vdi_id);
|
||||||
s->inode.vdi_size = offset;
|
s->inode.vdi_size = offset;
|
||||||
ret = write_object(fd, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id),
|
ret = write_object(fd, s->aio_context, (char *)&s->inode,
|
||||||
s->inode.nr_copies, datalen, 0, false, s->cache_flags);
|
vid_to_vdi_oid(s->inode.vdi_id), s->inode.nr_copies,
|
||||||
|
datalen, 0, false, s->cache_flags);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -1849,9 +1882,9 @@ static void coroutine_fn sd_write_done(SheepdogAIOCB *acb)
|
|||||||
iov.iov_base = &s->inode;
|
iov.iov_base = &s->inode;
|
||||||
iov.iov_len = sizeof(s->inode);
|
iov.iov_len = sizeof(s->inode);
|
||||||
aio_req = alloc_aio_req(s, acb, vid_to_vdi_oid(s->inode.vdi_id),
|
aio_req = alloc_aio_req(s, acb, vid_to_vdi_oid(s->inode.vdi_id),
|
||||||
data_len, offset, 0, 0, offset);
|
data_len, offset, 0, false, 0, offset);
|
||||||
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
|
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
|
||||||
add_aio_request(s, aio_req, &iov, 1, false, AIOCB_WRITE_UDATA);
|
add_aio_request(s, aio_req, &iov, 1, AIOCB_WRITE_UDATA);
|
||||||
|
|
||||||
acb->aio_done_func = sd_finish_aiocb;
|
acb->aio_done_func = sd_finish_aiocb;
|
||||||
acb->aiocb_type = AIOCB_WRITE_UDATA;
|
acb->aiocb_type = AIOCB_WRITE_UDATA;
|
||||||
@@ -1882,7 +1915,8 @@ static bool sd_delete(BDRVSheepdogState *s)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = do_req(fd, (SheepdogReq *)&hdr, s->name, &wlen, &rlen);
|
ret = do_req(fd, s->aio_context, (SheepdogReq *)&hdr,
|
||||||
|
s->name, &wlen, &rlen);
|
||||||
closesocket(fd);
|
closesocket(fd);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1939,8 +1973,8 @@ static int sd_create_branch(BDRVSheepdogState *s)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = read_object(fd, buf, vid_to_vdi_oid(vid), s->inode.nr_copies,
|
ret = read_object(fd, s->aio_context, buf, vid_to_vdi_oid(vid),
|
||||||
SD_INODE_SIZE, 0, s->cache_flags);
|
s->inode.nr_copies, SD_INODE_SIZE, 0, s->cache_flags);
|
||||||
|
|
||||||
closesocket(fd);
|
closesocket(fd);
|
||||||
|
|
||||||
@@ -2049,7 +2083,8 @@ static int coroutine_fn sd_co_rw_vector(void *p)
|
|||||||
DPRINTF("new oid %" PRIx64 "\n", oid);
|
DPRINTF("new oid %" PRIx64 "\n", oid);
|
||||||
}
|
}
|
||||||
|
|
||||||
aio_req = alloc_aio_req(s, acb, oid, len, offset, flags, old_oid, done);
|
aio_req = alloc_aio_req(s, acb, oid, len, offset, flags, create,
|
||||||
|
old_oid, done);
|
||||||
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
|
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
|
||||||
|
|
||||||
if (create) {
|
if (create) {
|
||||||
@@ -2058,7 +2093,7 @@ static int coroutine_fn sd_co_rw_vector(void *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov, create,
|
add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov,
|
||||||
acb->aiocb_type);
|
acb->aiocb_type);
|
||||||
done:
|
done:
|
||||||
offset = 0;
|
offset = 0;
|
||||||
@@ -2138,9 +2173,9 @@ static int coroutine_fn sd_co_flush_to_disk(BlockDriverState *bs)
|
|||||||
acb->aio_done_func = sd_finish_aiocb;
|
acb->aio_done_func = sd_finish_aiocb;
|
||||||
|
|
||||||
aio_req = alloc_aio_req(s, acb, vid_to_vdi_oid(s->inode.vdi_id),
|
aio_req = alloc_aio_req(s, acb, vid_to_vdi_oid(s->inode.vdi_id),
|
||||||
0, 0, 0, 0, 0);
|
0, 0, 0, false, 0, 0);
|
||||||
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
|
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
|
||||||
add_aio_request(s, aio_req, NULL, 0, false, acb->aiocb_type);
|
add_aio_request(s, aio_req, NULL, 0, acb->aiocb_type);
|
||||||
|
|
||||||
qemu_coroutine_yield();
|
qemu_coroutine_yield();
|
||||||
return acb->ret;
|
return acb->ret;
|
||||||
@@ -2187,8 +2222,9 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = write_object(fd, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id),
|
ret = write_object(fd, s->aio_context, (char *)&s->inode,
|
||||||
s->inode.nr_copies, datalen, 0, false, s->cache_flags);
|
vid_to_vdi_oid(s->inode.vdi_id), s->inode.nr_copies,
|
||||||
|
datalen, 0, false, s->cache_flags);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_report("failed to write snapshot's inode.");
|
error_report("failed to write snapshot's inode.");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@@ -2203,8 +2239,9 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = read_object(fd, (char *)inode, vid_to_vdi_oid(new_vid),
|
ret = read_object(fd, s->aio_context, (char *)inode,
|
||||||
s->inode.nr_copies, datalen, 0, s->cache_flags);
|
vid_to_vdi_oid(new_vid), s->inode.nr_copies, datalen, 0,
|
||||||
|
s->cache_flags);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_report("failed to read new inode info. %s", strerror(errno));
|
error_report("failed to read new inode info. %s", strerror(errno));
|
||||||
@@ -2311,7 +2348,8 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
|
|||||||
req.opcode = SD_OP_READ_VDIS;
|
req.opcode = SD_OP_READ_VDIS;
|
||||||
req.data_length = max;
|
req.data_length = max;
|
||||||
|
|
||||||
ret = do_req(fd, (SheepdogReq *)&req, vdi_inuse, &wlen, &rlen);
|
ret = do_req(fd, s->aio_context, (SheepdogReq *)&req,
|
||||||
|
vdi_inuse, &wlen, &rlen);
|
||||||
|
|
||||||
closesocket(fd);
|
closesocket(fd);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -2338,7 +2376,8 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* we don't need to read entire object */
|
/* we don't need to read entire object */
|
||||||
ret = read_object(fd, (char *)&inode, vid_to_vdi_oid(vid),
|
ret = read_object(fd, s->aio_context, (char *)&inode,
|
||||||
|
vid_to_vdi_oid(vid),
|
||||||
0, SD_INODE_SIZE - sizeof(inode.data_vdi_id), 0,
|
0, SD_INODE_SIZE - sizeof(inode.data_vdi_id), 0,
|
||||||
s->cache_flags);
|
s->cache_flags);
|
||||||
|
|
||||||
@@ -2403,11 +2442,11 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
|
|||||||
|
|
||||||
create = (offset == 0);
|
create = (offset == 0);
|
||||||
if (load) {
|
if (load) {
|
||||||
ret = read_object(fd, (char *)data, vmstate_oid,
|
ret = read_object(fd, s->aio_context, (char *)data, vmstate_oid,
|
||||||
s->inode.nr_copies, data_len, offset,
|
s->inode.nr_copies, data_len, offset,
|
||||||
s->cache_flags);
|
s->cache_flags);
|
||||||
} else {
|
} else {
|
||||||
ret = write_object(fd, (char *)data, vmstate_oid,
|
ret = write_object(fd, s->aio_context, (char *)data, vmstate_oid,
|
||||||
s->inode.nr_copies, data_len, offset, create,
|
s->inode.nr_copies, data_len, offset, create,
|
||||||
s->cache_flags);
|
s->cache_flags);
|
||||||
}
|
}
|
||||||
@@ -2529,28 +2568,32 @@ static int64_t sd_get_allocated_file_size(BlockDriverState *bs)
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QEMUOptionParameter sd_create_options[] = {
|
static QemuOptsList sd_create_opts = {
|
||||||
{
|
.name = "sheepdog-create-opts",
|
||||||
.name = BLOCK_OPT_SIZE,
|
.head = QTAILQ_HEAD_INITIALIZER(sd_create_opts.head),
|
||||||
.type = OPT_SIZE,
|
.desc = {
|
||||||
.help = "Virtual disk size"
|
{
|
||||||
},
|
.name = BLOCK_OPT_SIZE,
|
||||||
{
|
.type = QEMU_OPT_SIZE,
|
||||||
.name = BLOCK_OPT_BACKING_FILE,
|
.help = "Virtual disk size"
|
||||||
.type = OPT_STRING,
|
},
|
||||||
.help = "File name of a base image"
|
{
|
||||||
},
|
.name = BLOCK_OPT_BACKING_FILE,
|
||||||
{
|
.type = QEMU_OPT_STRING,
|
||||||
.name = BLOCK_OPT_PREALLOC,
|
.help = "File name of a base image"
|
||||||
.type = OPT_STRING,
|
},
|
||||||
.help = "Preallocation mode (allowed values: off, full)"
|
{
|
||||||
},
|
.name = BLOCK_OPT_PREALLOC,
|
||||||
{
|
.type = QEMU_OPT_STRING,
|
||||||
.name = BLOCK_OPT_REDUNDANCY,
|
.help = "Preallocation mode (allowed values: off, full)"
|
||||||
.type = OPT_STRING,
|
},
|
||||||
.help = "Redundancy of the image"
|
{
|
||||||
},
|
.name = BLOCK_OPT_REDUNDANCY,
|
||||||
{ NULL }
|
.type = QEMU_OPT_STRING,
|
||||||
|
.help = "Redundancy of the image"
|
||||||
|
},
|
||||||
|
{ /* end of list */ }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_sheepdog = {
|
static BlockDriver bdrv_sheepdog = {
|
||||||
@@ -2580,7 +2623,10 @@ static BlockDriver bdrv_sheepdog = {
|
|||||||
.bdrv_save_vmstate = sd_save_vmstate,
|
.bdrv_save_vmstate = sd_save_vmstate,
|
||||||
.bdrv_load_vmstate = sd_load_vmstate,
|
.bdrv_load_vmstate = sd_load_vmstate,
|
||||||
|
|
||||||
.create_options = sd_create_options,
|
.bdrv_detach_aio_context = sd_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = sd_attach_aio_context,
|
||||||
|
|
||||||
|
.create_opts = &sd_create_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_sheepdog_tcp = {
|
static BlockDriver bdrv_sheepdog_tcp = {
|
||||||
@@ -2610,7 +2656,10 @@ static BlockDriver bdrv_sheepdog_tcp = {
|
|||||||
.bdrv_save_vmstate = sd_save_vmstate,
|
.bdrv_save_vmstate = sd_save_vmstate,
|
||||||
.bdrv_load_vmstate = sd_load_vmstate,
|
.bdrv_load_vmstate = sd_load_vmstate,
|
||||||
|
|
||||||
.create_options = sd_create_options,
|
.bdrv_detach_aio_context = sd_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = sd_attach_aio_context,
|
||||||
|
|
||||||
|
.create_opts = &sd_create_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_sheepdog_unix = {
|
static BlockDriver bdrv_sheepdog_unix = {
|
||||||
@@ -2640,7 +2689,10 @@ static BlockDriver bdrv_sheepdog_unix = {
|
|||||||
.bdrv_save_vmstate = sd_save_vmstate,
|
.bdrv_save_vmstate = sd_save_vmstate,
|
||||||
.bdrv_load_vmstate = sd_load_vmstate,
|
.bdrv_load_vmstate = sd_load_vmstate,
|
||||||
|
|
||||||
.create_options = sd_create_options,
|
.bdrv_detach_aio_context = sd_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = sd_attach_aio_context,
|
||||||
|
|
||||||
|
.create_opts = &sd_create_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void bdrv_sheepdog_init(void)
|
static void bdrv_sheepdog_init(void)
|
||||||
|
|||||||
66
block/ssh.c
66
block/ssh.c
@@ -675,17 +675,20 @@ static int ssh_file_open(BlockDriverState *bs, QDict *options, int bdrv_flags,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QEMUOptionParameter ssh_create_options[] = {
|
static QemuOptsList ssh_create_opts = {
|
||||||
{
|
.name = "ssh-create-opts",
|
||||||
.name = BLOCK_OPT_SIZE,
|
.head = QTAILQ_HEAD_INITIALIZER(ssh_create_opts.head),
|
||||||
.type = OPT_SIZE,
|
.desc = {
|
||||||
.help = "Virtual disk size"
|
{
|
||||||
},
|
.name = BLOCK_OPT_SIZE,
|
||||||
{ NULL }
|
.type = QEMU_OPT_SIZE,
|
||||||
|
.help = "Virtual disk size"
|
||||||
|
},
|
||||||
|
{ /* end of list */ }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int ssh_create(const char *filename, QEMUOptionParameter *options,
|
static int ssh_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
int r, ret;
|
int r, ret;
|
||||||
int64_t total_size = 0;
|
int64_t total_size = 0;
|
||||||
@@ -697,12 +700,7 @@ static int ssh_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
ssh_state_init(&s);
|
ssh_state_init(&s);
|
||||||
|
|
||||||
/* Get desired file size. */
|
/* Get desired file size. */
|
||||||
while (options && options->name) {
|
total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
|
||||||
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
|
|
||||||
total_size = options->value.n;
|
|
||||||
}
|
|
||||||
options++;
|
|
||||||
}
|
|
||||||
DPRINTF("total_size=%" PRIi64, total_size);
|
DPRINTF("total_size=%" PRIi64, total_size);
|
||||||
|
|
||||||
uri_options = qdict_new();
|
uri_options = qdict_new();
|
||||||
@@ -773,7 +771,7 @@ static void restart_coroutine(void *opaque)
|
|||||||
qemu_coroutine_enter(co, NULL);
|
qemu_coroutine_enter(co, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn void set_fd_handler(BDRVSSHState *s)
|
static coroutine_fn void set_fd_handler(BDRVSSHState *s, BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
IOHandler *rd_handler = NULL, *wr_handler = NULL;
|
IOHandler *rd_handler = NULL, *wr_handler = NULL;
|
||||||
@@ -791,24 +789,26 @@ static coroutine_fn void set_fd_handler(BDRVSSHState *s)
|
|||||||
DPRINTF("s->sock=%d rd_handler=%p wr_handler=%p", s->sock,
|
DPRINTF("s->sock=%d rd_handler=%p wr_handler=%p", s->sock,
|
||||||
rd_handler, wr_handler);
|
rd_handler, wr_handler);
|
||||||
|
|
||||||
qemu_aio_set_fd_handler(s->sock, rd_handler, wr_handler, co);
|
aio_set_fd_handler(bdrv_get_aio_context(bs), s->sock,
|
||||||
|
rd_handler, wr_handler, co);
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn void clear_fd_handler(BDRVSSHState *s)
|
static coroutine_fn void clear_fd_handler(BDRVSSHState *s,
|
||||||
|
BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
DPRINTF("s->sock=%d", s->sock);
|
DPRINTF("s->sock=%d", s->sock);
|
||||||
qemu_aio_set_fd_handler(s->sock, NULL, NULL, NULL);
|
aio_set_fd_handler(bdrv_get_aio_context(bs), s->sock, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A non-blocking call returned EAGAIN, so yield, ensuring the
|
/* A non-blocking call returned EAGAIN, so yield, ensuring the
|
||||||
* handlers are set up so that we'll be rescheduled when there is an
|
* handlers are set up so that we'll be rescheduled when there is an
|
||||||
* interesting event on the socket.
|
* interesting event on the socket.
|
||||||
*/
|
*/
|
||||||
static coroutine_fn void co_yield(BDRVSSHState *s)
|
static coroutine_fn void co_yield(BDRVSSHState *s, BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
set_fd_handler(s);
|
set_fd_handler(s, bs);
|
||||||
qemu_coroutine_yield();
|
qemu_coroutine_yield();
|
||||||
clear_fd_handler(s);
|
clear_fd_handler(s, bs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SFTP has a function `libssh2_sftp_seek64' which seeks to a position
|
/* SFTP has a function `libssh2_sftp_seek64' which seeks to a position
|
||||||
@@ -838,7 +838,7 @@ static void ssh_seek(BDRVSSHState *s, int64_t offset, int flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static coroutine_fn int ssh_read(BDRVSSHState *s,
|
static coroutine_fn int ssh_read(BDRVSSHState *s, BlockDriverState *bs,
|
||||||
int64_t offset, size_t size,
|
int64_t offset, size_t size,
|
||||||
QEMUIOVector *qiov)
|
QEMUIOVector *qiov)
|
||||||
{
|
{
|
||||||
@@ -871,7 +871,7 @@ static coroutine_fn int ssh_read(BDRVSSHState *s,
|
|||||||
DPRINTF("sftp_read returned %zd", r);
|
DPRINTF("sftp_read returned %zd", r);
|
||||||
|
|
||||||
if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) {
|
if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) {
|
||||||
co_yield(s);
|
co_yield(s, bs);
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
@@ -906,14 +906,14 @@ static coroutine_fn int ssh_co_readv(BlockDriverState *bs,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
qemu_co_mutex_lock(&s->lock);
|
qemu_co_mutex_lock(&s->lock);
|
||||||
ret = ssh_read(s, sector_num * BDRV_SECTOR_SIZE,
|
ret = ssh_read(s, bs, sector_num * BDRV_SECTOR_SIZE,
|
||||||
nb_sectors * BDRV_SECTOR_SIZE, qiov);
|
nb_sectors * BDRV_SECTOR_SIZE, qiov);
|
||||||
qemu_co_mutex_unlock(&s->lock);
|
qemu_co_mutex_unlock(&s->lock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ssh_write(BDRVSSHState *s,
|
static int ssh_write(BDRVSSHState *s, BlockDriverState *bs,
|
||||||
int64_t offset, size_t size,
|
int64_t offset, size_t size,
|
||||||
QEMUIOVector *qiov)
|
QEMUIOVector *qiov)
|
||||||
{
|
{
|
||||||
@@ -941,7 +941,7 @@ static int ssh_write(BDRVSSHState *s,
|
|||||||
DPRINTF("sftp_write returned %zd", r);
|
DPRINTF("sftp_write returned %zd", r);
|
||||||
|
|
||||||
if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) {
|
if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) {
|
||||||
co_yield(s);
|
co_yield(s, bs);
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
@@ -960,7 +960,7 @@ static int ssh_write(BDRVSSHState *s,
|
|||||||
*/
|
*/
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
ssh_seek(s, offset + written, SSH_SEEK_WRITE|SSH_SEEK_FORCE);
|
ssh_seek(s, offset + written, SSH_SEEK_WRITE|SSH_SEEK_FORCE);
|
||||||
co_yield(s);
|
co_yield(s, bs);
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -988,7 +988,7 @@ static coroutine_fn int ssh_co_writev(BlockDriverState *bs,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
qemu_co_mutex_lock(&s->lock);
|
qemu_co_mutex_lock(&s->lock);
|
||||||
ret = ssh_write(s, sector_num * BDRV_SECTOR_SIZE,
|
ret = ssh_write(s, bs, sector_num * BDRV_SECTOR_SIZE,
|
||||||
nb_sectors * BDRV_SECTOR_SIZE, qiov);
|
nb_sectors * BDRV_SECTOR_SIZE, qiov);
|
||||||
qemu_co_mutex_unlock(&s->lock);
|
qemu_co_mutex_unlock(&s->lock);
|
||||||
|
|
||||||
@@ -1009,7 +1009,7 @@ static void unsafe_flush_warning(BDRVSSHState *s, const char *what)
|
|||||||
|
|
||||||
#ifdef HAS_LIBSSH2_SFTP_FSYNC
|
#ifdef HAS_LIBSSH2_SFTP_FSYNC
|
||||||
|
|
||||||
static coroutine_fn int ssh_flush(BDRVSSHState *s)
|
static coroutine_fn int ssh_flush(BDRVSSHState *s, BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@@ -1017,7 +1017,7 @@ static coroutine_fn int ssh_flush(BDRVSSHState *s)
|
|||||||
again:
|
again:
|
||||||
r = libssh2_sftp_fsync(s->sftp_handle);
|
r = libssh2_sftp_fsync(s->sftp_handle);
|
||||||
if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) {
|
if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) {
|
||||||
co_yield(s);
|
co_yield(s, bs);
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
if (r == LIBSSH2_ERROR_SFTP_PROTOCOL &&
|
if (r == LIBSSH2_ERROR_SFTP_PROTOCOL &&
|
||||||
@@ -1039,7 +1039,7 @@ static coroutine_fn int ssh_co_flush(BlockDriverState *bs)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
qemu_co_mutex_lock(&s->lock);
|
qemu_co_mutex_lock(&s->lock);
|
||||||
ret = ssh_flush(s);
|
ret = ssh_flush(s, bs);
|
||||||
qemu_co_mutex_unlock(&s->lock);
|
qemu_co_mutex_unlock(&s->lock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -1082,7 +1082,7 @@ static BlockDriver bdrv_ssh = {
|
|||||||
.bdrv_co_writev = ssh_co_writev,
|
.bdrv_co_writev = ssh_co_writev,
|
||||||
.bdrv_getlength = ssh_getlength,
|
.bdrv_getlength = ssh_getlength,
|
||||||
.bdrv_co_flush_to_disk = ssh_co_flush,
|
.bdrv_co_flush_to_disk = ssh_co_flush,
|
||||||
.create_options = ssh_create_options,
|
.create_opts = &ssh_create_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void bdrv_ssh_init(void)
|
static void bdrv_ssh_init(void)
|
||||||
|
|||||||
72
block/vdi.c
72
block/vdi.c
@@ -239,7 +239,6 @@ static void vdi_header_to_le(VdiHeader *header)
|
|||||||
cpu_to_le32s(&header->block_extra);
|
cpu_to_le32s(&header->block_extra);
|
||||||
cpu_to_le32s(&header->blocks_in_image);
|
cpu_to_le32s(&header->blocks_in_image);
|
||||||
cpu_to_le32s(&header->blocks_allocated);
|
cpu_to_le32s(&header->blocks_allocated);
|
||||||
cpu_to_le32s(&header->blocks_allocated);
|
|
||||||
uuid_convert(header->uuid_image);
|
uuid_convert(header->uuid_image);
|
||||||
uuid_convert(header->uuid_last_snap);
|
uuid_convert(header->uuid_last_snap);
|
||||||
uuid_convert(header->uuid_link);
|
uuid_convert(header->uuid_link);
|
||||||
@@ -673,8 +672,7 @@ static int vdi_co_write(BlockDriverState *bs,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vdi_create(const char *filename, QEMUOptionParameter *options,
|
static int vdi_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
@@ -689,25 +687,18 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
logout("\n");
|
logout("\n");
|
||||||
|
|
||||||
/* Read out options. */
|
/* Read out options. */
|
||||||
while (options && options->name) {
|
bytes = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
|
||||||
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
|
|
||||||
bytes = options->value.n;
|
|
||||||
#if defined(CONFIG_VDI_BLOCK_SIZE)
|
#if defined(CONFIG_VDI_BLOCK_SIZE)
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
|
/* TODO: Additional checks (SECTOR_SIZE * 2^n, ...). */
|
||||||
if (options->value.n) {
|
block_size = qemu_opt_get_size_del(opts,
|
||||||
/* TODO: Additional checks (SECTOR_SIZE * 2^n, ...). */
|
BLOCK_OPT_CLUSTER_SIZE,
|
||||||
block_size = options->value.n;
|
DEFAULT_CLUSTER_SIZE);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_VDI_STATIC_IMAGE)
|
#if defined(CONFIG_VDI_STATIC_IMAGE)
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_STATIC)) {
|
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_STATIC, false)) {
|
||||||
if (options->value.n) {
|
image_type = VDI_TYPE_STATIC;
|
||||||
image_type = VDI_TYPE_STATIC;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
options++;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (bytes > VDI_DISK_SIZE_MAX) {
|
if (bytes > VDI_DISK_SIZE_MAX) {
|
||||||
result = -ENOTSUP;
|
result = -ENOTSUP;
|
||||||
@@ -802,29 +793,34 @@ static void vdi_close(BlockDriverState *bs)
|
|||||||
error_free(s->migration_blocker);
|
error_free(s->migration_blocker);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QEMUOptionParameter vdi_create_options[] = {
|
static QemuOptsList vdi_create_opts = {
|
||||||
{
|
.name = "vdi-create-opts",
|
||||||
.name = BLOCK_OPT_SIZE,
|
.head = QTAILQ_HEAD_INITIALIZER(vdi_create_opts.head),
|
||||||
.type = OPT_SIZE,
|
.desc = {
|
||||||
.help = "Virtual disk size"
|
{
|
||||||
},
|
.name = BLOCK_OPT_SIZE,
|
||||||
|
.type = QEMU_OPT_SIZE,
|
||||||
|
.help = "Virtual disk size"
|
||||||
|
},
|
||||||
#if defined(CONFIG_VDI_BLOCK_SIZE)
|
#if defined(CONFIG_VDI_BLOCK_SIZE)
|
||||||
{
|
{
|
||||||
.name = BLOCK_OPT_CLUSTER_SIZE,
|
.name = BLOCK_OPT_CLUSTER_SIZE,
|
||||||
.type = OPT_SIZE,
|
.type = QEMU_OPT_SIZE,
|
||||||
.help = "VDI cluster (block) size",
|
.help = "VDI cluster (block) size",
|
||||||
.value = { .n = DEFAULT_CLUSTER_SIZE },
|
.def_value_str = stringify(DEFAULT_CLUSTER_SIZE)
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_VDI_STATIC_IMAGE)
|
#if defined(CONFIG_VDI_STATIC_IMAGE)
|
||||||
{
|
{
|
||||||
.name = BLOCK_OPT_STATIC,
|
.name = BLOCK_OPT_STATIC,
|
||||||
.type = OPT_FLAG,
|
.type = QEMU_OPT_BOOL,
|
||||||
.help = "VDI static (pre-allocated) image"
|
.help = "VDI static (pre-allocated) image",
|
||||||
},
|
.def_value_str = "off"
|
||||||
|
},
|
||||||
#endif
|
#endif
|
||||||
/* TODO: An additional option to set UUID values might be useful. */
|
/* TODO: An additional option to set UUID values might be useful. */
|
||||||
{ NULL }
|
{ /* end of list */ }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_vdi = {
|
static BlockDriver bdrv_vdi = {
|
||||||
@@ -846,7 +842,7 @@ static BlockDriver bdrv_vdi = {
|
|||||||
|
|
||||||
.bdrv_get_info = vdi_get_info,
|
.bdrv_get_info = vdi_get_info,
|
||||||
|
|
||||||
.create_options = vdi_create_options,
|
.create_opts = &vdi_create_opts,
|
||||||
.bdrv_check = vdi_check,
|
.bdrv_check = vdi_check,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
97
block/vhdx.c
97
block/vhdx.c
@@ -1723,8 +1723,7 @@ exit:
|
|||||||
* .---- ~ ----------- ~ ------------ ~ ---------------- ~ -----------.
|
* .---- ~ ----------- ~ ------------ ~ ---------------- ~ -----------.
|
||||||
* 1MB
|
* 1MB
|
||||||
*/
|
*/
|
||||||
static int vhdx_create(const char *filename, QEMUOptionParameter *options,
|
static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
uint64_t image_size = (uint64_t) 2 * GiB;
|
uint64_t image_size = (uint64_t) 2 * GiB;
|
||||||
@@ -1737,24 +1736,15 @@ static int vhdx_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
gunichar2 *creator = NULL;
|
gunichar2 *creator = NULL;
|
||||||
glong creator_items;
|
glong creator_items;
|
||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
const char *type = NULL;
|
char *type = NULL;
|
||||||
VHDXImageType image_type;
|
VHDXImageType image_type;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
while (options && options->name) {
|
image_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
|
||||||
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
|
log_size = qemu_opt_get_size_del(opts, VHDX_BLOCK_OPT_LOG_SIZE, 0);
|
||||||
image_size = options->value.n;
|
block_size = qemu_opt_get_size_del(opts, VHDX_BLOCK_OPT_BLOCK_SIZE, 0);
|
||||||
} else if (!strcmp(options->name, VHDX_BLOCK_OPT_LOG_SIZE)) {
|
type = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);
|
||||||
log_size = options->value.n;
|
use_zero_blocks = qemu_opt_get_bool_del(opts, VHDX_BLOCK_OPT_ZERO, false);
|
||||||
} else if (!strcmp(options->name, VHDX_BLOCK_OPT_BLOCK_SIZE)) {
|
|
||||||
block_size = options->value.n;
|
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) {
|
|
||||||
type = options->value.s;
|
|
||||||
} else if (!strcmp(options->name, VHDX_BLOCK_OPT_ZERO)) {
|
|
||||||
use_zero_blocks = options->value.n != 0;
|
|
||||||
}
|
|
||||||
options++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (image_size > VHDX_MAX_IMAGE_SIZE) {
|
if (image_size > VHDX_MAX_IMAGE_SIZE) {
|
||||||
error_setg_errno(errp, EINVAL, "Image size too large; max of 64TB");
|
error_setg_errno(errp, EINVAL, "Image size too large; max of 64TB");
|
||||||
@@ -1763,7 +1753,7 @@ static int vhdx_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type == NULL) {
|
if (type == NULL) {
|
||||||
type = "dynamic";
|
type = g_strdup("dynamic");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(type, "dynamic")) {
|
if (!strcmp(type, "dynamic")) {
|
||||||
@@ -1803,7 +1793,7 @@ static int vhdx_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
block_size = block_size > VHDX_BLOCK_SIZE_MAX ? VHDX_BLOCK_SIZE_MAX :
|
block_size = block_size > VHDX_BLOCK_SIZE_MAX ? VHDX_BLOCK_SIZE_MAX :
|
||||||
block_size;
|
block_size;
|
||||||
|
|
||||||
ret = bdrv_create_file(filename, options, &local_err);
|
ret = bdrv_create_file(filename, opts, &local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
goto exit;
|
goto exit;
|
||||||
@@ -1863,6 +1853,7 @@ static int vhdx_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
delete_and_exit:
|
delete_and_exit:
|
||||||
bdrv_unref(bs);
|
bdrv_unref(bs);
|
||||||
exit:
|
exit:
|
||||||
|
g_free(type);
|
||||||
g_free(creator);
|
g_free(creator);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -1885,37 +1876,41 @@ static int vhdx_check(BlockDriverState *bs, BdrvCheckResult *result,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QEMUOptionParameter vhdx_create_options[] = {
|
static QemuOptsList vhdx_create_opts = {
|
||||||
{
|
.name = "vhdx-create-opts",
|
||||||
.name = BLOCK_OPT_SIZE,
|
.head = QTAILQ_HEAD_INITIALIZER(vhdx_create_opts.head),
|
||||||
.type = OPT_SIZE,
|
.desc = {
|
||||||
.help = "Virtual disk size; max of 64TB."
|
{
|
||||||
},
|
.name = BLOCK_OPT_SIZE,
|
||||||
{
|
.type = QEMU_OPT_SIZE,
|
||||||
.name = VHDX_BLOCK_OPT_LOG_SIZE,
|
.help = "Virtual disk size; max of 64TB."
|
||||||
.type = OPT_SIZE,
|
},
|
||||||
.value.n = 1 * MiB,
|
{
|
||||||
.help = "Log size; min 1MB."
|
.name = VHDX_BLOCK_OPT_LOG_SIZE,
|
||||||
},
|
.type = QEMU_OPT_SIZE,
|
||||||
{
|
.def_value_str = stringify(DEFAULT_LOG_SIZE),
|
||||||
.name = VHDX_BLOCK_OPT_BLOCK_SIZE,
|
.help = "Log size; min 1MB."
|
||||||
.type = OPT_SIZE,
|
},
|
||||||
.value.n = 0,
|
{
|
||||||
.help = "Block Size; min 1MB, max 256MB. " \
|
.name = VHDX_BLOCK_OPT_BLOCK_SIZE,
|
||||||
"0 means auto-calculate based on image size."
|
.type = QEMU_OPT_SIZE,
|
||||||
},
|
.def_value_str = stringify(0),
|
||||||
{
|
.help = "Block Size; min 1MB, max 256MB. " \
|
||||||
.name = BLOCK_OPT_SUBFMT,
|
"0 means auto-calculate based on image size."
|
||||||
.type = OPT_STRING,
|
},
|
||||||
.help = "VHDX format type, can be either 'dynamic' or 'fixed'. "\
|
{
|
||||||
"Default is 'dynamic'."
|
.name = BLOCK_OPT_SUBFMT,
|
||||||
},
|
.type = QEMU_OPT_STRING,
|
||||||
{
|
.help = "VHDX format type, can be either 'dynamic' or 'fixed'. "\
|
||||||
.name = VHDX_BLOCK_OPT_ZERO,
|
"Default is 'dynamic'."
|
||||||
.type = OPT_FLAG,
|
},
|
||||||
.help = "Force use of payload blocks of type 'ZERO'. Non-standard."
|
{
|
||||||
},
|
.name = VHDX_BLOCK_OPT_ZERO,
|
||||||
{ NULL }
|
.type = QEMU_OPT_BOOL,
|
||||||
|
.help = "Force use of payload blocks of type 'ZERO'. Non-standard."
|
||||||
|
},
|
||||||
|
{ NULL }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_vhdx = {
|
static BlockDriver bdrv_vhdx = {
|
||||||
@@ -1931,7 +1926,7 @@ static BlockDriver bdrv_vhdx = {
|
|||||||
.bdrv_get_info = vhdx_get_info,
|
.bdrv_get_info = vhdx_get_info,
|
||||||
.bdrv_check = vhdx_check,
|
.bdrv_check = vhdx_check,
|
||||||
|
|
||||||
.create_options = vhdx_create_options,
|
.create_opts = &vhdx_create_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void bdrv_vhdx_init(void)
|
static void bdrv_vhdx_init(void)
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#define GiB (MiB * 1024)
|
#define GiB (MiB * 1024)
|
||||||
#define TiB ((uint64_t) GiB * 1024)
|
#define TiB ((uint64_t) GiB * 1024)
|
||||||
|
|
||||||
|
#define DEFAULT_LOG_SIZE 1048576 /* 1MiB */
|
||||||
/* Structures and fields present in the VHDX file */
|
/* Structures and fields present in the VHDX file */
|
||||||
|
|
||||||
/* The header section has the following blocks,
|
/* The header section has the following blocks,
|
||||||
|
|||||||
144
block/vmdk.c
144
block/vmdk.c
@@ -1695,17 +1695,16 @@ static int filename_decompose(const char *filename, char *path, char *prefix,
|
|||||||
return VMDK_OK;
|
return VMDK_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vmdk_create(const char *filename, QEMUOptionParameter *options,
|
static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
BlockDriverState *new_bs = NULL;
|
BlockDriverState *new_bs = NULL;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
char *desc = NULL;
|
char *desc = NULL;
|
||||||
int64_t total_size = 0, filesize;
|
int64_t total_size = 0, filesize;
|
||||||
const char *adapter_type = NULL;
|
char *adapter_type = NULL;
|
||||||
const char *backing_file = NULL;
|
char *backing_file = NULL;
|
||||||
const char *fmt = NULL;
|
char *fmt = NULL;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
bool flat, split, compress;
|
bool flat, split, compress;
|
||||||
@@ -1745,24 +1744,19 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
/* Read out options */
|
/* Read out options */
|
||||||
while (options && options->name) {
|
total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
|
||||||
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
|
adapter_type = qemu_opt_get_del(opts, BLOCK_OPT_ADAPTER_TYPE);
|
||||||
total_size = options->value.n;
|
backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_ADAPTER_TYPE)) {
|
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_COMPAT6, false)) {
|
||||||
adapter_type = options->value.s;
|
flags |= BLOCK_FLAG_COMPAT6;
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
|
|
||||||
backing_file = options->value.s;
|
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) {
|
|
||||||
flags |= options->value.n ? BLOCK_FLAG_COMPAT6 : 0;
|
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) {
|
|
||||||
fmt = options->value.s;
|
|
||||||
} else if (!strcmp(options->name, BLOCK_OPT_ZEROED_GRAIN)) {
|
|
||||||
zeroed_grain |= options->value.n;
|
|
||||||
}
|
|
||||||
options++;
|
|
||||||
}
|
}
|
||||||
|
fmt = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);
|
||||||
|
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ZEROED_GRAIN, false)) {
|
||||||
|
zeroed_grain = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!adapter_type) {
|
if (!adapter_type) {
|
||||||
adapter_type = "ide";
|
adapter_type = g_strdup("ide");
|
||||||
} else if (strcmp(adapter_type, "ide") &&
|
} else if (strcmp(adapter_type, "ide") &&
|
||||||
strcmp(adapter_type, "buslogic") &&
|
strcmp(adapter_type, "buslogic") &&
|
||||||
strcmp(adapter_type, "lsilogic") &&
|
strcmp(adapter_type, "lsilogic") &&
|
||||||
@@ -1778,7 +1772,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
}
|
}
|
||||||
if (!fmt) {
|
if (!fmt) {
|
||||||
/* Default format to monolithicSparse */
|
/* Default format to monolithicSparse */
|
||||||
fmt = "monolithicSparse";
|
fmt = g_strdup("monolithicSparse");
|
||||||
} else if (strcmp(fmt, "monolithicFlat") &&
|
} else if (strcmp(fmt, "monolithicFlat") &&
|
||||||
strcmp(fmt, "monolithicSparse") &&
|
strcmp(fmt, "monolithicSparse") &&
|
||||||
strcmp(fmt, "twoGbMaxExtentSparse") &&
|
strcmp(fmt, "twoGbMaxExtentSparse") &&
|
||||||
@@ -1879,7 +1873,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
if (!split && !flat) {
|
if (!split && !flat) {
|
||||||
desc_offset = 0x200;
|
desc_offset = 0x200;
|
||||||
} else {
|
} else {
|
||||||
ret = bdrv_create_file(filename, options, &local_err);
|
ret = bdrv_create_file(filename, opts, &local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
goto exit;
|
goto exit;
|
||||||
@@ -1909,6 +1903,9 @@ exit:
|
|||||||
if (new_bs) {
|
if (new_bs) {
|
||||||
bdrv_unref(new_bs);
|
bdrv_unref(new_bs);
|
||||||
}
|
}
|
||||||
|
g_free(adapter_type);
|
||||||
|
g_free(backing_file);
|
||||||
|
g_free(fmt);
|
||||||
g_free(desc);
|
g_free(desc);
|
||||||
g_string_free(ext_desc_lines, true);
|
g_string_free(ext_desc_lines, true);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -2096,41 +2093,68 @@ static int vmdk_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QEMUOptionParameter vmdk_create_options[] = {
|
static void vmdk_detach_aio_context(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
.name = BLOCK_OPT_SIZE,
|
BDRVVmdkState *s = bs->opaque;
|
||||||
.type = OPT_SIZE,
|
int i;
|
||||||
.help = "Virtual disk size"
|
|
||||||
},
|
for (i = 0; i < s->num_extents; i++) {
|
||||||
{
|
bdrv_detach_aio_context(s->extents[i].file);
|
||||||
.name = BLOCK_OPT_ADAPTER_TYPE,
|
}
|
||||||
.type = OPT_STRING,
|
}
|
||||||
.help = "Virtual adapter type, can be one of "
|
|
||||||
"ide (default), lsilogic, buslogic or legacyESX"
|
static void vmdk_attach_aio_context(BlockDriverState *bs,
|
||||||
},
|
AioContext *new_context)
|
||||||
{
|
{
|
||||||
.name = BLOCK_OPT_BACKING_FILE,
|
BDRVVmdkState *s = bs->opaque;
|
||||||
.type = OPT_STRING,
|
int i;
|
||||||
.help = "File name of a base image"
|
|
||||||
},
|
for (i = 0; i < s->num_extents; i++) {
|
||||||
{
|
bdrv_attach_aio_context(s->extents[i].file, new_context);
|
||||||
.name = BLOCK_OPT_COMPAT6,
|
}
|
||||||
.type = OPT_FLAG,
|
}
|
||||||
.help = "VMDK version 6 image"
|
|
||||||
},
|
static QemuOptsList vmdk_create_opts = {
|
||||||
{
|
.name = "vmdk-create-opts",
|
||||||
.name = BLOCK_OPT_SUBFMT,
|
.head = QTAILQ_HEAD_INITIALIZER(vmdk_create_opts.head),
|
||||||
.type = OPT_STRING,
|
.desc = {
|
||||||
.help =
|
{
|
||||||
"VMDK flat extent format, can be one of "
|
.name = BLOCK_OPT_SIZE,
|
||||||
"{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat | streamOptimized} "
|
.type = QEMU_OPT_SIZE,
|
||||||
},
|
.help = "Virtual disk size"
|
||||||
{
|
},
|
||||||
.name = BLOCK_OPT_ZEROED_GRAIN,
|
{
|
||||||
.type = OPT_FLAG,
|
.name = BLOCK_OPT_ADAPTER_TYPE,
|
||||||
.help = "Enable efficient zero writes using the zeroed-grain GTE feature"
|
.type = QEMU_OPT_STRING,
|
||||||
},
|
.help = "Virtual adapter type, can be one of "
|
||||||
{ NULL }
|
"ide (default), lsilogic, buslogic or legacyESX"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = BLOCK_OPT_BACKING_FILE,
|
||||||
|
.type = QEMU_OPT_STRING,
|
||||||
|
.help = "File name of a base image"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = BLOCK_OPT_COMPAT6,
|
||||||
|
.type = QEMU_OPT_BOOL,
|
||||||
|
.help = "VMDK version 6 image",
|
||||||
|
.def_value_str = "off"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = BLOCK_OPT_SUBFMT,
|
||||||
|
.type = QEMU_OPT_STRING,
|
||||||
|
.help =
|
||||||
|
"VMDK flat extent format, can be one of "
|
||||||
|
"{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat | streamOptimized} "
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = BLOCK_OPT_ZEROED_GRAIN,
|
||||||
|
.type = QEMU_OPT_BOOL,
|
||||||
|
.help = "Enable efficient zero writes "
|
||||||
|
"using the zeroed-grain GTE feature"
|
||||||
|
},
|
||||||
|
{ /* end of list */ }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_vmdk = {
|
static BlockDriver bdrv_vmdk = {
|
||||||
@@ -2153,8 +2177,10 @@ static BlockDriver bdrv_vmdk = {
|
|||||||
.bdrv_get_specific_info = vmdk_get_specific_info,
|
.bdrv_get_specific_info = vmdk_get_specific_info,
|
||||||
.bdrv_refresh_limits = vmdk_refresh_limits,
|
.bdrv_refresh_limits = vmdk_refresh_limits,
|
||||||
.bdrv_get_info = vmdk_get_info,
|
.bdrv_get_info = vmdk_get_info,
|
||||||
|
.bdrv_detach_aio_context = vmdk_detach_aio_context,
|
||||||
|
.bdrv_attach_aio_context = vmdk_attach_aio_context,
|
||||||
|
|
||||||
.create_options = vmdk_create_options,
|
.create_opts = &vmdk_create_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void bdrv_vmdk_init(void)
|
static void bdrv_vmdk_init(void)
|
||||||
|
|||||||
60
block/vpc.c
60
block/vpc.c
@@ -738,12 +738,11 @@ static int create_fixed_disk(int fd, uint8_t *buf, int64_t total_size)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vpc_create(const char *filename, QEMUOptionParameter *options,
|
static int vpc_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
uint8_t buf[1024];
|
uint8_t buf[1024];
|
||||||
VHDFooter *footer = (VHDFooter *) buf;
|
VHDFooter *footer = (VHDFooter *) buf;
|
||||||
QEMUOptionParameter *disk_type_param;
|
char *disk_type_param;
|
||||||
int fd, i;
|
int fd, i;
|
||||||
uint16_t cyls = 0;
|
uint16_t cyls = 0;
|
||||||
uint8_t heads = 0;
|
uint8_t heads = 0;
|
||||||
@@ -754,16 +753,16 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
int ret = -EIO;
|
int ret = -EIO;
|
||||||
|
|
||||||
/* Read out options */
|
/* Read out options */
|
||||||
total_size = get_option_parameter(options, BLOCK_OPT_SIZE)->value.n;
|
total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
|
||||||
|
disk_type_param = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);
|
||||||
disk_type_param = get_option_parameter(options, BLOCK_OPT_SUBFMT);
|
if (disk_type_param) {
|
||||||
if (disk_type_param && disk_type_param->value.s) {
|
if (!strcmp(disk_type_param, "dynamic")) {
|
||||||
if (!strcmp(disk_type_param->value.s, "dynamic")) {
|
|
||||||
disk_type = VHD_DYNAMIC;
|
disk_type = VHD_DYNAMIC;
|
||||||
} else if (!strcmp(disk_type_param->value.s, "fixed")) {
|
} else if (!strcmp(disk_type_param, "fixed")) {
|
||||||
disk_type = VHD_FIXED;
|
disk_type = VHD_FIXED;
|
||||||
} else {
|
} else {
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
disk_type = VHD_DYNAMIC;
|
disk_type = VHD_DYNAMIC;
|
||||||
@@ -772,7 +771,8 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
/* Create the file */
|
/* Create the file */
|
||||||
fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
|
fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
return -EIO;
|
ret = -EIO;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -837,8 +837,10 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
ret = create_fixed_disk(fd, buf, total_size);
|
ret = create_fixed_disk(fd, buf, total_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
qemu_close(fd);
|
qemu_close(fd);
|
||||||
|
out:
|
||||||
|
g_free(disk_type_param);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -866,20 +868,24 @@ static void vpc_close(BlockDriverState *bs)
|
|||||||
error_free(s->migration_blocker);
|
error_free(s->migration_blocker);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QEMUOptionParameter vpc_create_options[] = {
|
static QemuOptsList vpc_create_opts = {
|
||||||
{
|
.name = "vpc-create-opts",
|
||||||
.name = BLOCK_OPT_SIZE,
|
.head = QTAILQ_HEAD_INITIALIZER(vpc_create_opts.head),
|
||||||
.type = OPT_SIZE,
|
.desc = {
|
||||||
.help = "Virtual disk size"
|
{
|
||||||
},
|
.name = BLOCK_OPT_SIZE,
|
||||||
{
|
.type = QEMU_OPT_SIZE,
|
||||||
.name = BLOCK_OPT_SUBFMT,
|
.help = "Virtual disk size"
|
||||||
.type = OPT_STRING,
|
},
|
||||||
.help =
|
{
|
||||||
"Type of virtual hard disk format. Supported formats are "
|
.name = BLOCK_OPT_SUBFMT,
|
||||||
"{dynamic (default) | fixed} "
|
.type = QEMU_OPT_STRING,
|
||||||
},
|
.help =
|
||||||
{ NULL }
|
"Type of virtual hard disk format. Supported formats are "
|
||||||
|
"{dynamic (default) | fixed} "
|
||||||
|
},
|
||||||
|
{ /* end of list */ }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static BlockDriver bdrv_vpc = {
|
static BlockDriver bdrv_vpc = {
|
||||||
@@ -897,7 +903,7 @@ static BlockDriver bdrv_vpc = {
|
|||||||
|
|
||||||
.bdrv_get_info = vpc_get_info,
|
.bdrv_get_info = vpc_get_info,
|
||||||
|
|
||||||
.create_options = vpc_create_options,
|
.create_opts = &vpc_create_opts,
|
||||||
.bdrv_has_zero_init = vpc_has_zero_init,
|
.bdrv_has_zero_init = vpc_has_zero_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2910,8 +2910,8 @@ static BlockDriver vvfat_write_target = {
|
|||||||
|
|
||||||
static int enable_write_target(BDRVVVFATState *s, Error **errp)
|
static int enable_write_target(BDRVVVFATState *s, Error **errp)
|
||||||
{
|
{
|
||||||
BlockDriver *bdrv_qcow;
|
BlockDriver *bdrv_qcow = NULL;
|
||||||
QEMUOptionParameter *options;
|
QemuOpts *opts = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
int size = sector2cluster(s, s->sector_count);
|
int size = sector2cluster(s, s->sector_count);
|
||||||
s->used_clusters = calloc(size, 1);
|
s->used_clusters = calloc(size, 1);
|
||||||
@@ -2926,12 +2926,12 @@ static int enable_write_target(BDRVVVFATState *s, Error **errp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bdrv_qcow = bdrv_find_format("qcow");
|
bdrv_qcow = bdrv_find_format("qcow");
|
||||||
options = parse_option_parameters("", bdrv_qcow->create_options, NULL);
|
opts = qemu_opts_create(bdrv_qcow->create_opts, NULL, 0, &error_abort);
|
||||||
set_option_parameter_int(options, BLOCK_OPT_SIZE, s->sector_count * 512);
|
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s->sector_count * 512);
|
||||||
set_option_parameter(options, BLOCK_OPT_BACKING_FILE, "fat:");
|
qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:");
|
||||||
|
|
||||||
ret = bdrv_create(bdrv_qcow, s->qcow_filename, options, errp);
|
ret = bdrv_create(bdrv_qcow, s->qcow_filename, opts, errp);
|
||||||
free_option_parameters(options);
|
qemu_opts_del(opts);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ struct QEMUWin32AIOState {
|
|||||||
HANDLE hIOCP;
|
HANDLE hIOCP;
|
||||||
EventNotifier e;
|
EventNotifier e;
|
||||||
int count;
|
int count;
|
||||||
|
bool is_aio_context_attached;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct QEMUWin32AIOCB {
|
typedef struct QEMUWin32AIOCB {
|
||||||
@@ -114,7 +115,7 @@ static void win32_aio_cancel(BlockDriverAIOCB *blockacb)
|
|||||||
* wait for completion.
|
* wait for completion.
|
||||||
*/
|
*/
|
||||||
while (!HasOverlappedIoCompleted(&waiocb->ov)) {
|
while (!HasOverlappedIoCompleted(&waiocb->ov)) {
|
||||||
qemu_aio_wait();
|
aio_poll(bdrv_get_aio_context(blockacb->bs), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,6 +181,20 @@ int win32_aio_attach(QEMUWin32AIOState *aio, HANDLE hfile)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void win32_aio_detach_aio_context(QEMUWin32AIOState *aio,
|
||||||
|
AioContext *old_context)
|
||||||
|
{
|
||||||
|
aio_set_event_notifier(old_context, &aio->e, NULL);
|
||||||
|
aio->is_aio_context_attached = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void win32_aio_attach_aio_context(QEMUWin32AIOState *aio,
|
||||||
|
AioContext *new_context)
|
||||||
|
{
|
||||||
|
aio->is_aio_context_attached = true;
|
||||||
|
aio_set_event_notifier(new_context, &aio->e, win32_aio_completion_cb);
|
||||||
|
}
|
||||||
|
|
||||||
QEMUWin32AIOState *win32_aio_init(void)
|
QEMUWin32AIOState *win32_aio_init(void)
|
||||||
{
|
{
|
||||||
QEMUWin32AIOState *s;
|
QEMUWin32AIOState *s;
|
||||||
@@ -194,8 +209,6 @@ QEMUWin32AIOState *win32_aio_init(void)
|
|||||||
goto out_close_efd;
|
goto out_close_efd;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_aio_set_event_notifier(&s->e, win32_aio_completion_cb);
|
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
|
||||||
out_close_efd:
|
out_close_efd:
|
||||||
@@ -204,3 +217,11 @@ out_free_state:
|
|||||||
g_free(s);
|
g_free(s);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void win32_aio_cleanup(QEMUWin32AIOState *aio)
|
||||||
|
{
|
||||||
|
assert(!aio->is_aio_context_attached);
|
||||||
|
CloseHandle(aio->hIOCP);
|
||||||
|
event_notifier_cleanup(&aio->e);
|
||||||
|
g_free(aio);
|
||||||
|
}
|
||||||
|
|||||||
54
blockdev.c
54
blockdev.c
@@ -106,7 +106,7 @@ void blockdev_auto_del(BlockDriverState *bs)
|
|||||||
DriveInfo *dinfo = drive_get_by_blockdev(bs);
|
DriveInfo *dinfo = drive_get_by_blockdev(bs);
|
||||||
|
|
||||||
if (dinfo && dinfo->auto_del) {
|
if (dinfo && dinfo->auto_del) {
|
||||||
drive_put_ref(dinfo);
|
drive_del(dinfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +213,7 @@ static void bdrv_format_print(void *opaque, const char *name)
|
|||||||
error_printf(" %s", name);
|
error_printf(" %s", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drive_uninit(DriveInfo *dinfo)
|
void drive_del(DriveInfo *dinfo)
|
||||||
{
|
{
|
||||||
if (dinfo->opts) {
|
if (dinfo->opts) {
|
||||||
qemu_opts_del(dinfo->opts);
|
qemu_opts_del(dinfo->opts);
|
||||||
@@ -226,19 +226,6 @@ static void drive_uninit(DriveInfo *dinfo)
|
|||||||
g_free(dinfo);
|
g_free(dinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drive_put_ref(DriveInfo *dinfo)
|
|
||||||
{
|
|
||||||
assert(dinfo->refcount);
|
|
||||||
if (--dinfo->refcount == 0) {
|
|
||||||
drive_uninit(dinfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void drive_get_ref(DriveInfo *dinfo)
|
|
||||||
{
|
|
||||||
dinfo->refcount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
QEMUBH *bh;
|
QEMUBH *bh;
|
||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
@@ -329,7 +316,6 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
|
|||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
const char *buf;
|
const char *buf;
|
||||||
const char *serial;
|
|
||||||
int ro = 0;
|
int ro = 0;
|
||||||
int bdrv_flags = 0;
|
int bdrv_flags = 0;
|
||||||
int on_read_error, on_write_error;
|
int on_read_error, on_write_error;
|
||||||
@@ -371,8 +357,6 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
|
|||||||
ro = qemu_opt_get_bool(opts, "read-only", 0);
|
ro = qemu_opt_get_bool(opts, "read-only", 0);
|
||||||
copy_on_read = qemu_opt_get_bool(opts, "copy-on-read", false);
|
copy_on_read = qemu_opt_get_bool(opts, "copy-on-read", false);
|
||||||
|
|
||||||
serial = qemu_opt_get(opts, "serial");
|
|
||||||
|
|
||||||
if ((buf = qemu_opt_get(opts, "discard")) != NULL) {
|
if ((buf = qemu_opt_get(opts, "discard")) != NULL) {
|
||||||
if (bdrv_parse_discard_flags(buf, &bdrv_flags) != 0) {
|
if (bdrv_parse_discard_flags(buf, &bdrv_flags) != 0) {
|
||||||
error_setg(errp, "invalid discard option");
|
error_setg(errp, "invalid discard option");
|
||||||
@@ -500,10 +484,6 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
|
|||||||
dinfo->bdrv->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
|
dinfo->bdrv->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
|
||||||
dinfo->bdrv->read_only = ro;
|
dinfo->bdrv->read_only = ro;
|
||||||
dinfo->bdrv->detect_zeroes = detect_zeroes;
|
dinfo->bdrv->detect_zeroes = detect_zeroes;
|
||||||
dinfo->refcount = 1;
|
|
||||||
if (serial != NULL) {
|
|
||||||
dinfo->serial = g_strdup(serial);
|
|
||||||
}
|
|
||||||
QTAILQ_INSERT_TAIL(&drives, dinfo, next);
|
QTAILQ_INSERT_TAIL(&drives, dinfo, next);
|
||||||
|
|
||||||
bdrv_set_on_error(dinfo->bdrv, on_read_error, on_write_error);
|
bdrv_set_on_error(dinfo->bdrv, on_read_error, on_write_error);
|
||||||
@@ -629,6 +609,10 @@ QemuOptsList qemu_legacy_drive_opts = {
|
|||||||
.name = "addr",
|
.name = "addr",
|
||||||
.type = QEMU_OPT_STRING,
|
.type = QEMU_OPT_STRING,
|
||||||
.help = "pci address (virtio only)",
|
.help = "pci address (virtio only)",
|
||||||
|
},{
|
||||||
|
.name = "serial",
|
||||||
|
.type = QEMU_OPT_STRING,
|
||||||
|
.help = "disk serial number",
|
||||||
},{
|
},{
|
||||||
.name = "file",
|
.name = "file",
|
||||||
.type = QEMU_OPT_STRING,
|
.type = QEMU_OPT_STRING,
|
||||||
@@ -658,7 +642,7 @@ QemuOptsList qemu_legacy_drive_opts = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
|
DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
|
||||||
{
|
{
|
||||||
const char *value;
|
const char *value;
|
||||||
DriveInfo *dinfo = NULL;
|
DriveInfo *dinfo = NULL;
|
||||||
@@ -672,6 +656,7 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
|
|||||||
const char *werror, *rerror;
|
const char *werror, *rerror;
|
||||||
bool read_only = false;
|
bool read_only = false;
|
||||||
bool copy_on_read;
|
bool copy_on_read;
|
||||||
|
const char *serial;
|
||||||
const char *filename;
|
const char *filename;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
@@ -875,6 +860,9 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Serial number */
|
||||||
|
serial = qemu_opt_get(legacy_opts, "serial");
|
||||||
|
|
||||||
/* no id supplied -> create one */
|
/* no id supplied -> create one */
|
||||||
if (qemu_opts_id(all_opts) == NULL) {
|
if (qemu_opts_id(all_opts) == NULL) {
|
||||||
char *new_id;
|
char *new_id;
|
||||||
@@ -965,6 +953,8 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
|
|||||||
dinfo->unit = unit_id;
|
dinfo->unit = unit_id;
|
||||||
dinfo->devaddr = devaddr;
|
dinfo->devaddr = devaddr;
|
||||||
|
|
||||||
|
dinfo->serial = g_strdup(serial);
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case IF_IDE:
|
case IF_IDE:
|
||||||
case IF_SCSI:
|
case IF_SCSI:
|
||||||
@@ -1703,6 +1693,7 @@ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
|
|||||||
{
|
{
|
||||||
ThrottleConfig cfg;
|
ThrottleConfig cfg;
|
||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
|
AioContext *aio_context;
|
||||||
|
|
||||||
bs = bdrv_find(device);
|
bs = bdrv_find(device);
|
||||||
if (!bs) {
|
if (!bs) {
|
||||||
@@ -1746,6 +1737,9 @@ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aio_context = bdrv_get_aio_context(bs);
|
||||||
|
aio_context_acquire(aio_context);
|
||||||
|
|
||||||
if (!bs->io_limits_enabled && throttle_enabled(&cfg)) {
|
if (!bs->io_limits_enabled && throttle_enabled(&cfg)) {
|
||||||
bdrv_io_limits_enable(bs);
|
bdrv_io_limits_enable(bs);
|
||||||
} else if (bs->io_limits_enabled && !throttle_enabled(&cfg)) {
|
} else if (bs->io_limits_enabled && !throttle_enabled(&cfg)) {
|
||||||
@@ -1755,6 +1749,8 @@ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
|
|||||||
if (bs->io_limits_enabled) {
|
if (bs->io_limits_enabled) {
|
||||||
bdrv_set_io_limits(bs, &cfg);
|
bdrv_set_io_limits(bs, &cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aio_context_release(aio_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
|
int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
|
||||||
@@ -1791,7 +1787,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
|
|||||||
bdrv_set_on_error(bs, BLOCKDEV_ON_ERROR_REPORT,
|
bdrv_set_on_error(bs, BLOCKDEV_ON_ERROR_REPORT,
|
||||||
BLOCKDEV_ON_ERROR_REPORT);
|
BLOCKDEV_ON_ERROR_REPORT);
|
||||||
} else {
|
} else {
|
||||||
drive_uninit(drive_get_by_blockdev(bs));
|
drive_del(drive_get_by_blockdev(bs));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2334,9 +2330,9 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO Sort it out in raw-posix and drive_init: Reject aio=native with
|
/* TODO Sort it out in raw-posix and drive_new(): Reject aio=native with
|
||||||
* cache.direct=false instead of silently switching to aio=threads, except
|
* cache.direct=false instead of silently switching to aio=threads, except
|
||||||
* if called from drive_init.
|
* when called from drive_new().
|
||||||
*
|
*
|
||||||
* For now, simply forbidding the combination for all drivers will do. */
|
* For now, simply forbidding the combination for all drivers will do. */
|
||||||
if (options->has_aio && options->aio == BLOCKDEV_AIO_OPTIONS_NATIVE) {
|
if (options->has_aio && options->aio == BLOCKDEV_AIO_OPTIONS_NATIVE) {
|
||||||
@@ -2368,7 +2364,7 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bdrv_key_required(dinfo->bdrv)) {
|
if (bdrv_key_required(dinfo->bdrv)) {
|
||||||
drive_uninit(dinfo);
|
drive_del(dinfo);
|
||||||
error_setg(errp, "blockdev-add doesn't support encrypted devices");
|
error_setg(errp, "blockdev-add doesn't support encrypted devices");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@@ -2431,10 +2427,6 @@ QemuOptsList qemu_common_drive_opts = {
|
|||||||
.name = "format",
|
.name = "format",
|
||||||
.type = QEMU_OPT_STRING,
|
.type = QEMU_OPT_STRING,
|
||||||
.help = "disk format (raw, qcow2, ...)",
|
.help = "disk format (raw, qcow2, ...)",
|
||||||
},{
|
|
||||||
.name = "serial",
|
|
||||||
.type = QEMU_OPT_STRING,
|
|
||||||
.help = "disk serial number",
|
|
||||||
},{
|
},{
|
||||||
.name = "rerror",
|
.name = "rerror",
|
||||||
.type = QEMU_OPT_STRING,
|
.type = QEMU_OPT_STRING,
|
||||||
|
|||||||
@@ -1,7 +1,37 @@
|
|||||||
{ TARGET_FREEBSD_NR___getcwd, "__getcwd", NULL, NULL, NULL },
|
/*
|
||||||
|
* FreeBSD strace list
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
{ TARGET_FREEBSD_NR___acl_aclcheck_fd, "__acl_aclcheck_fd", "%s(%d, %d, %#x)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR___acl_aclcheck_file, "__acl_aclcheck_file", "%s(\"%s\", %d, %#x)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR___acl_aclcheck_link, "__acl_aclcheck_link", "%s(\"%s\", %d, %#x)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR___acl_delete_fd, "__acl_delete_fd", "%s(%d, %d)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR___acl_delete_file, "__acl_delete_file", "%s(\"%s\", %d)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR___acl_delete_link, "__acl_delete_link", "%s(\"%s\", %d)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR___acl_get_fd, "__acl_get_fd", "%s(%d, %d, %#x)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR___acl_get_file, "__acl_get_file", "%s(\"%s\", %d, %#x)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR___acl_get_link, "__acl_get_link", "%s(\"%s\", %d, %#x)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR___acl_set_fd, "__acl_set_fd", "%s(%d, %d, %#x)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR___acl_set_file, "__acl_set_file", "%s(\"%s\", %d, %#x)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR___acl_set_link, "__acl_set_link", "%s(\"%s\", %d, %#x)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR___semctl, "__semctl", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR___semctl, "__semctl", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR___syscall, "__syscall", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR___syscall, "__syscall", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, print_sysctl, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR__umtx_op, "_umtx_op", "%s(%#x, %d, %d, %#x, %#x)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_accept, "accept", "%s(%d,%#x,%#x)", NULL, NULL },
|
{ TARGET_FREEBSD_NR_accept, "accept", "%s(%d,%#x,%#x)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_access, "access", "%s(\"%s\",%#o)", NULL, NULL },
|
{ TARGET_FREEBSD_NR_access, "access", "%s(\"%s\",%#o)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_acct, "acct", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_acct, "acct", NULL, NULL, NULL },
|
||||||
@@ -20,24 +50,41 @@
|
|||||||
{ TARGET_FREEBSD_NR_connect, "connect", "%s(%d,%#x,%d)", NULL, NULL },
|
{ TARGET_FREEBSD_NR_connect, "connect", "%s(%d,%#x,%d)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_dup, "dup", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_dup, "dup", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_dup2, "dup2", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_dup2, "dup2", NULL, NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_eaccess, "eaccess", "%s(\"%s\",%#x)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_execve, "execve", NULL, print_execve, NULL },
|
{ TARGET_FREEBSD_NR_execve, "execve", NULL, print_execve, NULL },
|
||||||
{ TARGET_FREEBSD_NR_exit, "exit", "%s(%d)\n", NULL, NULL },
|
{ TARGET_FREEBSD_NR_exit, "exit", "%s(%d)\n", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_extattrctl, "extattrctl", "%s(\"%s\", %d, \"%s\", %d, \"%s\"", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_extattr_delete_fd, "extattr_delete_fd", "%s(%d, %d, \"%s\")", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_extattr_delete_file, "extattr_delete_file", "%s(\"%s\", %d, \"%s\")", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_extattr_delete_link, "extattr_delete_link", "%s(\"%s\", %d, \"%s\")", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_extattr_get_fd, "extattr_get_fd", "%s(%d, %d, \"%s\", %#x, %d)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_extattr_get_file, "extattr_get_file", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_extattr_get_file, "extattr_get_link", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_extattr_list_fd, "extattr_list_fd", "%s(%d, %d, %#x, %d)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_extattr_list_file, "extattr_list_file", "%s(\"%s\", %d, %#x, %d)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_extattr_list_link, "extattr_list_link", "%s(\"%s\", %d, %#x, %d)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_extattr_set_fd, "extattr_set_fd", "%s(%d, %d, \"%s\", %#x, %d)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_extattr_set_file, "extattr_set_file", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_extattr_set_link, "extattr_set_link", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_fchdir, "fchdir", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_fchdir, "fchdir", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_fchflags, "fchflags", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_fchflags, "fchflags", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_fchmod, "fchmod", "%s(%d,%#o)", NULL, NULL },
|
{ TARGET_FREEBSD_NR_fchmod, "fchmod", "%s(%d,%#o)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_fchown, "fchown", "%s(\"%s\",%d,%d)", NULL, NULL },
|
{ TARGET_FREEBSD_NR_fchown, "fchown", "%s(%d,%d,%d)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_fcntl, "fcntl", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_fcntl, "fcntl", NULL, NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_fexecve, "fexecve", NULL, print_execve, NULL },
|
||||||
{ TARGET_FREEBSD_NR_fhopen, "fhopen", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_fhopen, "fhopen", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_fhstat, "fhstat", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_fhstat, "fhstat", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_fhstatfs, "fhstatfs", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_fhstatfs, "fhstatfs", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_flock, "flock", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_flock, "flock", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_fork, "fork", "%s()", NULL, NULL },
|
{ TARGET_FREEBSD_NR_fork, "fork", "%s()", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_fpathconf, "fpathconf", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_fpathconf, "fpathconf", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_fstat, "fstat", "%s(%d,%p)", NULL, NULL },
|
{ TARGET_FREEBSD_NR_fstat, "fstat", "%s(%d,%#x)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_fstatfs, "fstatfs", "%s(%d,%p)", NULL, NULL },
|
{ TARGET_FREEBSD_NR_fstatat, "fstatat", "%s(%d,\"%s\", %#x, %d)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_fstatfs, "fstatfs", "%s(%d,%#x)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_fsync, "fsync", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_fsync, "fsync", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_ftruncate, "ftruncate", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_ftruncate, "ftruncate", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_futimes, "futimes", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_futimes, "futimes", NULL, NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_getcontext, "getcontext", "%s(%#x)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_getdirentries, "getdirentries", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_getdirentries, "getdirentries", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_freebsd6_mmap, "freebsd6_mmap", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_freebsd6_mmap, "freebsd6_mmap", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_getegid, "getegid", "%s()", NULL, NULL },
|
{ TARGET_FREEBSD_NR_getegid, "getegid", "%s()", NULL, NULL },
|
||||||
@@ -63,7 +110,7 @@
|
|||||||
{ TARGET_FREEBSD_NR_getsockopt, "getsockopt", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_getsockopt, "getsockopt", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_gettimeofday, "gettimeofday", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_gettimeofday, "gettimeofday", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_getuid, "getuid", "%s()", NULL, NULL },
|
{ TARGET_FREEBSD_NR_getuid, "getuid", "%s()", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_ioctl, "ioctl", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_ioctl, "ioctl", NULL, print_ioctl, NULL },
|
||||||
{ TARGET_FREEBSD_NR_issetugid, "issetugid", "%s()", NULL, NULL },
|
{ TARGET_FREEBSD_NR_issetugid, "issetugid", "%s()", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_kevent, "kevent", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_kevent, "kevent", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_kill, "kill", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_kill, "kill", NULL, NULL, NULL },
|
||||||
@@ -72,6 +119,7 @@
|
|||||||
{ TARGET_FREEBSD_NR_lchown, "lchown", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_lchown, "lchown", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_link, "link", "%s(\"%s\",\"%s\")", NULL, NULL },
|
{ TARGET_FREEBSD_NR_link, "link", "%s(\"%s\",\"%s\")", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_listen, "listen", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_listen, "listen", NULL, NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_lpathconf, "lpathconf", "%s(\"%s\", %d)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_lseek, "lseek", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_lseek, "lseek", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_lstat, "lstat", "%s(\"%s\",%p)", NULL, NULL },
|
{ TARGET_FREEBSD_NR_lstat, "lstat", "%s(\"%s\",%p)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_madvise, "madvise", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_madvise, "madvise", NULL, NULL, NULL },
|
||||||
@@ -96,7 +144,8 @@
|
|||||||
{ TARGET_FREEBSD_NR_nanosleep, "nanosleep", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_nanosleep, "nanosleep", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_nfssvc, "nfssvc", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_nfssvc, "nfssvc", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_open, "open", "%s(\"%s\",%#x,%#o)", NULL, NULL },
|
{ TARGET_FREEBSD_NR_open, "open", "%s(\"%s\",%#x,%#o)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_pathconf, "pathconf", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_openat, "openat", "%s(%d, \"%s\",%#x,%#o)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_pathconf, "pathconf", "%s(\"%s\", %d)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_pipe, "pipe", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_pipe, "pipe", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_poll, "poll", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_poll, "poll", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_pread, "pread", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_pread, "pread", NULL, NULL, NULL },
|
||||||
@@ -116,6 +165,7 @@
|
|||||||
{ TARGET_FREEBSD_NR_revoke, "revoke", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_revoke, "revoke", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_rfork, "rfork", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_rfork, "rfork", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_rmdir, "rmdir", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_rmdir, "rmdir", NULL, NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_rtprio_thread, "rtprio_thread", "%s(%d, %d, %p)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_sbrk, "sbrk", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_sbrk, "sbrk", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_sched_yield, "sched_yield", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_sched_yield, "sched_yield", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_select, "select", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_select, "select", NULL, NULL, NULL },
|
||||||
@@ -123,6 +173,7 @@
|
|||||||
{ TARGET_FREEBSD_NR_semop, "semop", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_semop, "semop", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_sendmsg, "sendmsg", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_sendmsg, "sendmsg", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_sendto, "sendto", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_sendto, "sendto", NULL, NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_setcontext, "setcontext", "%s(%#x)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_setegid, "setegid", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_setegid, "setegid", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_seteuid, "seteuid", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_seteuid, "seteuid", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_setgid, "setgid", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_setgid, "setgid", NULL, NULL, NULL },
|
||||||
@@ -151,7 +202,7 @@
|
|||||||
{ TARGET_FREEBSD_NR_sigprocmask, "sigprocmask", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_sigprocmask, "sigprocmask", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_sigreturn, "sigreturn", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_sigreturn, "sigreturn", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_sigsuspend, "sigsuspend", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_sigsuspend, "sigsuspend", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_socket, "socket", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_socket, "socket", "%s(%d,%d,%d)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_socketpair, "socketpair", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_socketpair, "socketpair", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_sstk, "sstk", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_sstk, "sstk", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_stat, "stat", "%s(\"%s\",%p)", NULL, NULL },
|
{ TARGET_FREEBSD_NR_stat, "stat", "%s(\"%s\",%p)", NULL, NULL },
|
||||||
@@ -160,6 +211,15 @@
|
|||||||
{ TARGET_FREEBSD_NR_sync, "sync", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_sync, "sync", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_sysarch, "sysarch", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_sysarch, "sysarch", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_syscall, "syscall", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_syscall, "syscall", NULL, NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_thr_create, "thr_create", "%s(%#x, %#x, %d)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_thr_exit, "thr_exit", "%s(%#x)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_thr_kill, "thr_kill", "%s(%d, %#x)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_thr_kill2, "thr_kill2", "%s(%d, %d, %d)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_thr_new, "thr_new", "%s(%#x, %d)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_thr_self, "thr_self", "%s(%#x)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_thr_set_name, "thr_set_name", "%s(%d, \"%s\")", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_thr_suspend, "thr_suspend", "%s(%d, %#x)", NULL, NULL },
|
||||||
|
{ TARGET_FREEBSD_NR_thr_wake, "thr_wake", "%s(%d)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_truncate, "truncate", NULL, NULL, NULL },
|
{ TARGET_FREEBSD_NR_truncate, "truncate", NULL, NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_umask, "umask", "%s(%#o)", NULL, NULL },
|
{ TARGET_FREEBSD_NR_umask, "umask", "%s(%#o)", NULL, NULL },
|
||||||
{ TARGET_FREEBSD_NR_unlink, "unlink", "%s(\"%s\")", NULL, NULL },
|
{ TARGET_FREEBSD_NR_unlink, "unlink", "%s(\"%s\")", NULL, NULL },
|
||||||
|
|||||||
@@ -1,373 +1,450 @@
|
|||||||
/*
|
/*
|
||||||
* System call numbers.
|
* System call numbers.
|
||||||
*
|
*
|
||||||
* $FreeBSD: src/sys/sys/syscall.h,v 1.224 2008/08/24 21:23:08 rwatson Exp $
|
* created from FreeBSD: releng/9.1/sys/kern/syscalls.master 229723
|
||||||
* created from FreeBSD: head/sys/kern/syscalls.master 182123 2008-08-24 21:20:35Z rwatson
|
* 2012-01-06 19:29:16Z jhb
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define TARGET_FREEBSD_NR_syscall 0
|
#define TARGET_FREEBSD_NR_syscall 0
|
||||||
#define TARGET_FREEBSD_NR_exit 1
|
#define TARGET_FREEBSD_NR_exit 1
|
||||||
#define TARGET_FREEBSD_NR_fork 2
|
#define TARGET_FREEBSD_NR_fork 2
|
||||||
#define TARGET_FREEBSD_NR_read 3
|
#define TARGET_FREEBSD_NR_read 3
|
||||||
#define TARGET_FREEBSD_NR_write 4
|
#define TARGET_FREEBSD_NR_write 4
|
||||||
#define TARGET_FREEBSD_NR_open 5
|
#define TARGET_FREEBSD_NR_open 5
|
||||||
#define TARGET_FREEBSD_NR_close 6
|
#define TARGET_FREEBSD_NR_close 6
|
||||||
#define TARGET_FREEBSD_NR_wait4 7
|
#define TARGET_FREEBSD_NR_wait4 7
|
||||||
#define TARGET_FREEBSD_NR_link 9
|
/* 8 is old creat */
|
||||||
#define TARGET_FREEBSD_NR_unlink 10
|
#define TARGET_FREEBSD_NR_link 9
|
||||||
#define TARGET_FREEBSD_NR_chdir 12
|
#define TARGET_FREEBSD_NR_unlink 10
|
||||||
#define TARGET_FREEBSD_NR_fchdir 13
|
/* 11 is obsolete execv */
|
||||||
#define TARGET_FREEBSD_NR_mknod 14
|
#define TARGET_FREEBSD_NR_chdir 12
|
||||||
#define TARGET_FREEBSD_NR_chmod 15
|
#define TARGET_FREEBSD_NR_fchdir 13
|
||||||
#define TARGET_FREEBSD_NR_chown 16
|
#define TARGET_FREEBSD_NR_mknod 14
|
||||||
#define TARGET_FREEBSD_NR_break 17
|
#define TARGET_FREEBSD_NR_chmod 15
|
||||||
#define TARGET_FREEBSD_NR_freebsd4_getfsstat 18
|
#define TARGET_FREEBSD_NR_chown 16
|
||||||
#define TARGET_FREEBSD_NR_getpid 20
|
#define TARGET_FREEBSD_NR_break 17
|
||||||
#define TARGET_FREEBSD_NR_mount 21
|
#define TARGET_FREEBSD_NR_freebsd4_getfsstat 18
|
||||||
#define TARGET_FREEBSD_NR_unmount 22
|
/* 19 is old lseek */
|
||||||
#define TARGET_FREEBSD_NR_setuid 23
|
#define TARGET_FREEBSD_NR_getpid 20
|
||||||
#define TARGET_FREEBSD_NR_getuid 24
|
#define TARGET_FREEBSD_NR_mount 21
|
||||||
#define TARGET_FREEBSD_NR_geteuid 25
|
#define TARGET_FREEBSD_NR_unmount 22
|
||||||
#define TARGET_FREEBSD_NR_ptrace 26
|
#define TARGET_FREEBSD_NR_setuid 23
|
||||||
#define TARGET_FREEBSD_NR_recvmsg 27
|
#define TARGET_FREEBSD_NR_getuid 24
|
||||||
#define TARGET_FREEBSD_NR_sendmsg 28
|
#define TARGET_FREEBSD_NR_geteuid 25
|
||||||
#define TARGET_FREEBSD_NR_recvfrom 29
|
#define TARGET_FREEBSD_NR_ptrace 26
|
||||||
#define TARGET_FREEBSD_NR_accept 30
|
#define TARGET_FREEBSD_NR_recvmsg 27
|
||||||
#define TARGET_FREEBSD_NR_getpeername 31
|
#define TARGET_FREEBSD_NR_sendmsg 28
|
||||||
#define TARGET_FREEBSD_NR_getsockname 32
|
#define TARGET_FREEBSD_NR_recvfrom 29
|
||||||
#define TARGET_FREEBSD_NR_access 33
|
#define TARGET_FREEBSD_NR_accept 30
|
||||||
#define TARGET_FREEBSD_NR_chflags 34
|
#define TARGET_FREEBSD_NR_getpeername 31
|
||||||
#define TARGET_FREEBSD_NR_fchflags 35
|
#define TARGET_FREEBSD_NR_getsockname 32
|
||||||
#define TARGET_FREEBSD_NR_sync 36
|
#define TARGET_FREEBSD_NR_access 33
|
||||||
#define TARGET_FREEBSD_NR_kill 37
|
#define TARGET_FREEBSD_NR_chflags 34
|
||||||
#define TARGET_FREEBSD_NR_getppid 39
|
#define TARGET_FREEBSD_NR_fchflags 35
|
||||||
#define TARGET_FREEBSD_NR_dup 41
|
#define TARGET_FREEBSD_NR_sync 36
|
||||||
#define TARGET_FREEBSD_NR_pipe 42
|
#define TARGET_FREEBSD_NR_kill 37
|
||||||
#define TARGET_FREEBSD_NR_getegid 43
|
/* 38 is old stat */
|
||||||
#define TARGET_FREEBSD_NR_profil 44
|
#define TARGET_FREEBSD_NR_getppid 39
|
||||||
#define TARGET_FREEBSD_NR_ktrace 45
|
/* 40 is old lstat */
|
||||||
#define TARGET_FREEBSD_NR_getgid 47
|
#define TARGET_FREEBSD_NR_dup 41
|
||||||
#define TARGET_FREEBSD_NR_getlogin 49
|
#define TARGET_FREEBSD_NR_pipe 42
|
||||||
#define TARGET_FREEBSD_NR_setlogin 50
|
#define TARGET_FREEBSD_NR_getegid 43
|
||||||
#define TARGET_FREEBSD_NR_acct 51
|
#define TARGET_FREEBSD_NR_profil 44
|
||||||
#define TARGET_FREEBSD_NR_sigaltstack 53
|
#define TARGET_FREEBSD_NR_ktrace 45
|
||||||
#define TARGET_FREEBSD_NR_ioctl 54
|
/* 46 is old sigaction */
|
||||||
#define TARGET_FREEBSD_NR_reboot 55
|
#define TARGET_FREEBSD_NR_getgid 47
|
||||||
#define TARGET_FREEBSD_NR_revoke 56
|
/* 48 is old sigprocmask */
|
||||||
#define TARGET_FREEBSD_NR_symlink 57
|
#define TARGET_FREEBSD_NR_getlogin 49
|
||||||
#define TARGET_FREEBSD_NR_readlink 58
|
#define TARGET_FREEBSD_NR_setlogin 50
|
||||||
#define TARGET_FREEBSD_NR_execve 59
|
#define TARGET_FREEBSD_NR_acct 51
|
||||||
#define TARGET_FREEBSD_NR_umask 60
|
/* 52 is old sigpending */
|
||||||
#define TARGET_FREEBSD_NR_chroot 61
|
#define TARGET_FREEBSD_NR_sigaltstack 53
|
||||||
#define TARGET_FREEBSD_NR_msync 65
|
#define TARGET_FREEBSD_NR_ioctl 54
|
||||||
#define TARGET_FREEBSD_NR_vfork 66
|
#define TARGET_FREEBSD_NR_reboot 55
|
||||||
#define TARGET_FREEBSD_NR_sbrk 69
|
#define TARGET_FREEBSD_NR_revoke 56
|
||||||
#define TARGET_FREEBSD_NR_sstk 70
|
#define TARGET_FREEBSD_NR_symlink 57
|
||||||
#define TARGET_FREEBSD_NR_vadvise 72
|
#define TARGET_FREEBSD_NR_readlink 58
|
||||||
#define TARGET_FREEBSD_NR_munmap 73
|
#define TARGET_FREEBSD_NR_execve 59
|
||||||
#define TARGET_FREEBSD_NR_mprotect 74
|
#define TARGET_FREEBSD_NR_umask 60
|
||||||
#define TARGET_FREEBSD_NR_madvise 75
|
#define TARGET_FREEBSD_NR_chroot 61
|
||||||
#define TARGET_FREEBSD_NR_mincore 78
|
/* 62 is old fstat */
|
||||||
#define TARGET_FREEBSD_NR_getgroups 79
|
/* 63 is old getkerninfo */
|
||||||
#define TARGET_FREEBSD_NR_setgroups 80
|
/* 64 is old getpagesize */
|
||||||
#define TARGET_FREEBSD_NR_getpgrp 81
|
#define TARGET_FREEBSD_NR_msync 65
|
||||||
#define TARGET_FREEBSD_NR_setpgid 82
|
#define TARGET_FREEBSD_NR_vfork 66
|
||||||
#define TARGET_FREEBSD_NR_setitimer 83
|
/* 67 is obsolete vread */
|
||||||
#define TARGET_FREEBSD_NR_swapon 85
|
/* 68 is obsolete vwrite */
|
||||||
#define TARGET_FREEBSD_NR_getitimer 86
|
#define TARGET_FREEBSD_NR_sbrk 69
|
||||||
#define TARGET_FREEBSD_NR_getdtablesize 89
|
#define TARGET_FREEBSD_NR_sstk 70
|
||||||
#define TARGET_FREEBSD_NR_dup2 90
|
/* 71 is old mmap */
|
||||||
#define TARGET_FREEBSD_NR_fcntl 92
|
#define TARGET_FREEBSD_NR_vadvise 72
|
||||||
#define TARGET_FREEBSD_NR_select 93
|
#define TARGET_FREEBSD_NR_munmap 73
|
||||||
#define TARGET_FREEBSD_NR_fsync 95
|
#define TARGET_FREEBSD_NR_mprotect 74
|
||||||
#define TARGET_FREEBSD_NR_setpriority 96
|
#define TARGET_FREEBSD_NR_madvise 75
|
||||||
#define TARGET_FREEBSD_NR_socket 97
|
/* 76 is obsolete vhangup */
|
||||||
#define TARGET_FREEBSD_NR_connect 98
|
/* 77 is obsolete vlimit */
|
||||||
#define TARGET_FREEBSD_NR_getpriority 100
|
#define TARGET_FREEBSD_NR_mincore 78
|
||||||
#define TARGET_FREEBSD_NR_bind 104
|
#define TARGET_FREEBSD_NR_getgroups 79
|
||||||
#define TARGET_FREEBSD_NR_setsockopt 105
|
#define TARGET_FREEBSD_NR_setgroups 80
|
||||||
#define TARGET_FREEBSD_NR_listen 106
|
#define TARGET_FREEBSD_NR_getpgrp 81
|
||||||
#define TARGET_FREEBSD_NR_gettimeofday 116
|
#define TARGET_FREEBSD_NR_setpgid 82
|
||||||
#define TARGET_FREEBSD_NR_getrusage 117
|
#define TARGET_FREEBSD_NR_setitimer 83
|
||||||
#define TARGET_FREEBSD_NR_getsockopt 118
|
/* 84 is old wait */
|
||||||
#define TARGET_FREEBSD_NR_readv 120
|
#define TARGET_FREEBSD_NR_swapon 85
|
||||||
#define TARGET_FREEBSD_NR_writev 121
|
#define TARGET_FREEBSD_NR_getitimer 86
|
||||||
#define TARGET_FREEBSD_NR_settimeofday 122
|
/* 87 is old gethostname */
|
||||||
#define TARGET_FREEBSD_NR_fchown 123
|
/* 88 is old sethostname */
|
||||||
#define TARGET_FREEBSD_NR_fchmod 124
|
#define TARGET_FREEBSD_NR_getdtablesize 89
|
||||||
#define TARGET_FREEBSD_NR_setreuid 126
|
#define TARGET_FREEBSD_NR_dup2 90
|
||||||
#define TARGET_FREEBSD_NR_setregid 127
|
#define TARGET_FREEBSD_NR_fcntl 92
|
||||||
#define TARGET_FREEBSD_NR_rename 128
|
#define TARGET_FREEBSD_NR_select 93
|
||||||
#define TARGET_FREEBSD_NR_flock 131
|
#define TARGET_FREEBSD_NR_fsync 95
|
||||||
#define TARGET_FREEBSD_NR_mkfifo 132
|
#define TARGET_FREEBSD_NR_setpriority 96
|
||||||
#define TARGET_FREEBSD_NR_sendto 133
|
#define TARGET_FREEBSD_NR_socket 97
|
||||||
#define TARGET_FREEBSD_NR_shutdown 134
|
#define TARGET_FREEBSD_NR_connect 98
|
||||||
#define TARGET_FREEBSD_NR_socketpair 135
|
/* 99 is old accept */
|
||||||
#define TARGET_FREEBSD_NR_mkdir 136
|
#define TARGET_FREEBSD_NR_getpriority 100
|
||||||
#define TARGET_FREEBSD_NR_rmdir 137
|
/* 101 is old send */
|
||||||
#define TARGET_FREEBSD_NR_utimes 138
|
/* 102 is old recv */
|
||||||
#define TARGET_FREEBSD_NR_adjtime 140
|
/* 103 is old sigreturn */
|
||||||
#define TARGET_FREEBSD_NR_setsid 147
|
#define TARGET_FREEBSD_NR_bind 104
|
||||||
#define TARGET_FREEBSD_NR_quotactl 148
|
#define TARGET_FREEBSD_NR_setsockopt 105
|
||||||
#define TARGET_FREEBSD_NR_nlm_syscall 154
|
#define TARGET_FREEBSD_NR_listen 106
|
||||||
#define TARGET_FREEBSD_NR_nfssvc 155
|
/* 107 is obsolete vtimes */
|
||||||
#define TARGET_FREEBSD_NR_freebsd4_statfs 157
|
/* 108 is old sigvec */
|
||||||
#define TARGET_FREEBSD_NR_freebsd4_fstatfs 158
|
/* 109 is old sigblock */
|
||||||
#define TARGET_FREEBSD_NR_lgetfh 160
|
/* 110 is old sigsetmask */
|
||||||
#define TARGET_FREEBSD_NR_getfh 161
|
/* 111 is old sigsuspend */
|
||||||
#define TARGET_FREEBSD_NR_getdomainname 162
|
/* 112 is old sigstack */
|
||||||
#define TARGET_FREEBSD_NR_setdomainname 163
|
/* 113 is old recvmsg */
|
||||||
#define TARGET_FREEBSD_NR_uname 164
|
/* 114 is old sendmsg */
|
||||||
#define TARGET_FREEBSD_NR_sysarch 165
|
/* 115 is obsolete vtrace */
|
||||||
#define TARGET_FREEBSD_NR_rtprio 166
|
#define TARGET_FREEBSD_NR_gettimeofday 116
|
||||||
#define TARGET_FREEBSD_NR_semsys 169
|
#define TARGET_FREEBSD_NR_getrusage 117
|
||||||
#define TARGET_FREEBSD_NR_msgsys 170
|
#define TARGET_FREEBSD_NR_getsockopt 118
|
||||||
#define TARGET_FREEBSD_NR_shmsys 171
|
#define TARGET_FREEBSD_NR_readv 120
|
||||||
#define TARGET_FREEBSD_NR_freebsd6_pread 173
|
#define TARGET_FREEBSD_NR_writev 121
|
||||||
#define TARGET_FREEBSD_NR_freebsd6_pwrite 174
|
#define TARGET_FREEBSD_NR_settimeofday 122
|
||||||
#define TARGET_FREEBSD_NR_setfib 175
|
#define TARGET_FREEBSD_NR_fchown 123
|
||||||
#define TARGET_FREEBSD_NR_ntp_adjtime 176
|
#define TARGET_FREEBSD_NR_fchmod 124
|
||||||
#define TARGET_FREEBSD_NR_setgid 181
|
/* 125 is old recvfrom */
|
||||||
#define TARGET_FREEBSD_NR_setegid 182
|
#define TARGET_FREEBSD_NR_setreuid 126
|
||||||
#define TARGET_FREEBSD_NR_seteuid 183
|
#define TARGET_FREEBSD_NR_setregid 127
|
||||||
#define TARGET_FREEBSD_NR_stat 188
|
#define TARGET_FREEBSD_NR_rename 128
|
||||||
#define TARGET_FREEBSD_NR_fstat 189
|
/* 129 is old truncate */
|
||||||
#define TARGET_FREEBSD_NR_lstat 190
|
/* 130 is old ftruncate */
|
||||||
#define TARGET_FREEBSD_NR_pathconf 191
|
#define TARGET_FREEBSD_NR_flock 131
|
||||||
#define TARGET_FREEBSD_NR_fpathconf 192
|
#define TARGET_FREEBSD_NR_mkfifo 132
|
||||||
#define TARGET_FREEBSD_NR_getrlimit 194
|
#define TARGET_FREEBSD_NR_sendto 133
|
||||||
#define TARGET_FREEBSD_NR_setrlimit 195
|
#define TARGET_FREEBSD_NR_shutdown 134
|
||||||
#define TARGET_FREEBSD_NR_getdirentries 196
|
#define TARGET_FREEBSD_NR_socketpair 135
|
||||||
#define TARGET_FREEBSD_NR_freebsd6_mmap 197
|
#define TARGET_FREEBSD_NR_mkdir 136
|
||||||
#define TARGET_FREEBSD_NR___syscall 198
|
#define TARGET_FREEBSD_NR_rmdir 137
|
||||||
#define TARGET_FREEBSD_NR_freebsd6_lseek 199
|
#define TARGET_FREEBSD_NR_utimes 138
|
||||||
#define TARGET_FREEBSD_NR_freebsd6_truncate 200
|
/* 139 is obsolete 4.2 sigreturn */
|
||||||
#define TARGET_FREEBSD_NR_freebsd6_ftruncate 201
|
#define TARGET_FREEBSD_NR_adjtime 140
|
||||||
#define TARGET_FREEBSD_NR___sysctl 202
|
/* 141 is old getpeername */
|
||||||
#define TARGET_FREEBSD_NR_mlock 203
|
/* 142 is old gethostid */
|
||||||
#define TARGET_FREEBSD_NR_munlock 204
|
/* 143 is old sethostid */
|
||||||
#define TARGET_FREEBSD_NR_undelete 205
|
/* 144 is old getrlimit */
|
||||||
#define TARGET_FREEBSD_NR_futimes 206
|
/* 145 is old setrlimit */
|
||||||
#define TARGET_FREEBSD_NR_getpgid 207
|
/* 146 is old killpg */
|
||||||
#define TARGET_FREEBSD_NR_poll 209
|
#define TARGET_FREEBSD_NR_killpg 146 /* COMPAT */
|
||||||
#define TARGET_FREEBSD_NR___semctl 220
|
#define TARGET_FREEBSD_NR_setsid 147
|
||||||
#define TARGET_FREEBSD_NR_semget 221
|
#define TARGET_FREEBSD_NR_quotactl 148
|
||||||
#define TARGET_FREEBSD_NR_semop 222
|
/* 149 is old quota */
|
||||||
#define TARGET_FREEBSD_NR_msgctl 224
|
/* 150 is old getsockname */
|
||||||
#define TARGET_FREEBSD_NR_msgget 225
|
#define TARGET_FREEBSD_NR_nlm_syscall 154
|
||||||
#define TARGET_FREEBSD_NR_msgsnd 226
|
#define TARGET_FREEBSD_NR_nfssvc 155
|
||||||
#define TARGET_FREEBSD_NR_msgrcv 227
|
/* 156 is old getdirentries */
|
||||||
#define TARGET_FREEBSD_NR_shmat 228
|
#define TARGET_FREEBSD_NR_freebsd4_statfs 157
|
||||||
#define TARGET_FREEBSD_NR_shmctl 229
|
#define TARGET_FREEBSD_NR_freebsd4_fstatfs 158
|
||||||
#define TARGET_FREEBSD_NR_shmdt 230
|
#define TARGET_FREEBSD_NR_lgetfh 160
|
||||||
#define TARGET_FREEBSD_NR_shmget 231
|
#define TARGET_FREEBSD_NR_getfh 161
|
||||||
#define TARGET_FREEBSD_NR_clock_gettime 232
|
#define TARGET_FREEBSD_NR_freebsd4_getdomainname 162
|
||||||
#define TARGET_FREEBSD_NR_clock_settime 233
|
#define TARGET_FREEBSD_NR_freebsd4_setdomainname 163
|
||||||
#define TARGET_FREEBSD_NR_clock_getres 234
|
#define TARGET_FREEBSD_NR_freebsd4_uname 164
|
||||||
#define TARGET_FREEBSD_NR_ktimer_create 235
|
#define TARGET_FREEBSD_NR_sysarch 165
|
||||||
#define TARGET_FREEBSD_NR_ktimer_delete 236
|
#define TARGET_FREEBSD_NR_rtprio 166
|
||||||
#define TARGET_FREEBSD_NR_ktimer_settime 237
|
#define TARGET_FREEBSD_NR_semsys 169
|
||||||
#define TARGET_FREEBSD_NR_ktimer_gettime 238
|
#define TARGET_FREEBSD_NR_msgsys 170
|
||||||
#define TARGET_FREEBSD_NR_ktimer_getoverrun 239
|
#define TARGET_FREEBSD_NR_shmsys 171
|
||||||
#define TARGET_FREEBSD_NR_nanosleep 240
|
#define TARGET_FREEBSD_NR_freebsd6_pread 173
|
||||||
#define TARGET_FREEBSD_NR_ntp_gettime 248
|
#define TARGET_FREEBSD_NR_freebsd6_pwrite 174
|
||||||
#define TARGET_FREEBSD_NR_minherit 250
|
#define TARGET_FREEBSD_NR_setfib 175
|
||||||
#define TARGET_FREEBSD_NR_rfork 251
|
#define TARGET_FREEBSD_NR_ntp_adjtime 176
|
||||||
#define TARGET_FREEBSD_NR_openbsd_poll 252
|
#define TARGET_FREEBSD_NR_setgid 181
|
||||||
#define TARGET_FREEBSD_NR_issetugid 253
|
#define TARGET_FREEBSD_NR_setegid 182
|
||||||
#define TARGET_FREEBSD_NR_lchown 254
|
#define TARGET_FREEBSD_NR_seteuid 183
|
||||||
#define TARGET_FREEBSD_NR_aio_read 255
|
#define TARGET_FREEBSD_NR_stat 188
|
||||||
#define TARGET_FREEBSD_NR_aio_write 256
|
#define TARGET_FREEBSD_NR_fstat 189
|
||||||
#define TARGET_FREEBSD_NR_lio_listio 257
|
#define TARGET_FREEBSD_NR_lstat 190
|
||||||
#define TARGET_FREEBSD_NR_getdents 272
|
#define TARGET_FREEBSD_NR_pathconf 191
|
||||||
#define TARGET_FREEBSD_NR_lchmod 274
|
#define TARGET_FREEBSD_NR_fpathconf 192
|
||||||
#define TARGET_FREEBSD_NR_netbsd_lchown 275
|
#define TARGET_FREEBSD_NR_getrlimit 194
|
||||||
#define TARGET_FREEBSD_NR_lutimes 276
|
#define TARGET_FREEBSD_NR_setrlimit 195
|
||||||
#define TARGET_FREEBSD_NR_netbsd_msync 277
|
#define TARGET_FREEBSD_NR_getdirentries 196
|
||||||
#define TARGET_FREEBSD_NR_nstat 278
|
#define TARGET_FREEBSD_NR_freebsd6_mmap 197
|
||||||
#define TARGET_FREEBSD_NR_nfstat 279
|
#define TARGET_FREEBSD_NR___syscall 198
|
||||||
#define TARGET_FREEBSD_NR_nlstat 280
|
#define TARGET_FREEBSD_NR_freebsd6_lseek 199
|
||||||
#define TARGET_FREEBSD_NR_preadv 289
|
#define TARGET_FREEBSD_NR_freebsd6_truncate 200
|
||||||
#define TARGET_FREEBSD_NR_pwritev 290
|
#define TARGET_FREEBSD_NR_freebsd6_ftruncate 201
|
||||||
#define TARGET_FREEBSD_NR_freebsd4_fhstatfs 297
|
#define TARGET_FREEBSD_NR___sysctl 202
|
||||||
#define TARGET_FREEBSD_NR_fhopen 298
|
#define TARGET_FREEBSD_NR_mlock 203
|
||||||
#define TARGET_FREEBSD_NR_fhstat 299
|
#define TARGET_FREEBSD_NR_munlock 204
|
||||||
#define TARGET_FREEBSD_NR_modnext 300
|
#define TARGET_FREEBSD_NR_undelete 205
|
||||||
#define TARGET_FREEBSD_NR_modstat 301
|
#define TARGET_FREEBSD_NR_futimes 206
|
||||||
#define TARGET_FREEBSD_NR_modfnext 302
|
#define TARGET_FREEBSD_NR_getpgid 207
|
||||||
#define TARGET_FREEBSD_NR_modfind 303
|
#define TARGET_FREEBSD_NR_poll 209
|
||||||
#define TARGET_FREEBSD_NR_kldload 304
|
#define TARGET_FREEBSD_NR_freebsd7___semctl 220
|
||||||
#define TARGET_FREEBSD_NR_kldunload 305
|
#define TARGET_FREEBSD_NR_semget 221
|
||||||
#define TARGET_FREEBSD_NR_kldfind 306
|
#define TARGET_FREEBSD_NR_semop 222
|
||||||
#define TARGET_FREEBSD_NR_kldnext 307
|
#define TARGET_FREEBSD_NR_freebsd7_msgctl 224
|
||||||
#define TARGET_FREEBSD_NR_kldstat 308
|
#define TARGET_FREEBSD_NR_msgget 225
|
||||||
#define TARGET_FREEBSD_NR_kldfirstmod 309
|
#define TARGET_FREEBSD_NR_msgsnd 226
|
||||||
#define TARGET_FREEBSD_NR_getsid 310
|
#define TARGET_FREEBSD_NR_msgrcv 227
|
||||||
#define TARGET_FREEBSD_NR_setresuid 311
|
#define TARGET_FREEBSD_NR_shmat 228
|
||||||
#define TARGET_FREEBSD_NR_setresgid 312
|
#define TARGET_FREEBSD_NR_freebsd7_shmctl 229
|
||||||
#define TARGET_FREEBSD_NR_aio_return 314
|
#define TARGET_FREEBSD_NR_shmdt 230
|
||||||
#define TARGET_FREEBSD_NR_aio_suspend 315
|
#define TARGET_FREEBSD_NR_shmget 231
|
||||||
#define TARGET_FREEBSD_NR_aio_cancel 316
|
#define TARGET_FREEBSD_NR_clock_gettime 232
|
||||||
#define TARGET_FREEBSD_NR_aio_error 317
|
#define TARGET_FREEBSD_NR_clock_settime 233
|
||||||
#define TARGET_FREEBSD_NR_oaio_read 318
|
#define TARGET_FREEBSD_NR_clock_getres 234
|
||||||
#define TARGET_FREEBSD_NR_oaio_write 319
|
#define TARGET_FREEBSD_NR_ktimer_create 235
|
||||||
#define TARGET_FREEBSD_NR_olio_listio 320
|
#define TARGET_FREEBSD_NR_ktimer_delete 236
|
||||||
#define TARGET_FREEBSD_NR_yield 321
|
#define TARGET_FREEBSD_NR_ktimer_settime 237
|
||||||
#define TARGET_FREEBSD_NR_mlockall 324
|
#define TARGET_FREEBSD_NR_ktimer_gettime 238
|
||||||
#define TARGET_FREEBSD_NR_munlockall 325
|
#define TARGET_FREEBSD_NR_ktimer_getoverrun 239
|
||||||
#define TARGET_FREEBSD_NR___getcwd 326
|
#define TARGET_FREEBSD_NR_nanosleep 240
|
||||||
#define TARGET_FREEBSD_NR_sched_setparam 327
|
#define TARGET_FREEBSD_NR_ntp_gettime 248
|
||||||
#define TARGET_FREEBSD_NR_sched_getparam 328
|
#define TARGET_FREEBSD_NR_minherit 250
|
||||||
#define TARGET_FREEBSD_NR_sched_setscheduler 329
|
#define TARGET_FREEBSD_NR_rfork 251
|
||||||
#define TARGET_FREEBSD_NR_sched_getscheduler 330
|
#define TARGET_FREEBSD_NR_openbsd_poll 252
|
||||||
#define TARGET_FREEBSD_NR_sched_yield 331
|
#define TARGET_FREEBSD_NR_issetugid 253
|
||||||
#define TARGET_FREEBSD_NR_sched_get_priority_max 332
|
#define TARGET_FREEBSD_NR_lchown 254
|
||||||
#define TARGET_FREEBSD_NR_sched_get_priority_min 333
|
#define TARGET_FREEBSD_NR_aio_read 255
|
||||||
#define TARGET_FREEBSD_NR_sched_rr_get_interval 334
|
#define TARGET_FREEBSD_NR_aio_write 256
|
||||||
#define TARGET_FREEBSD_NR_utrace 335
|
#define TARGET_FREEBSD_NR_lio_listio 257
|
||||||
#define TARGET_FREEBSD_NR_freebsd4_sendfile 336
|
#define TARGET_FREEBSD_NR_getdents 272
|
||||||
#define TARGET_FREEBSD_NR_kldsym 337
|
#define TARGET_FREEBSD_NR_lchmod 274
|
||||||
#define TARGET_FREEBSD_NR_jail 338
|
#define TARGET_FREEBSD_NR_netbsd_lchown 275
|
||||||
#define TARGET_FREEBSD_NR_sigprocmask 340
|
#define TARGET_FREEBSD_NR_lutimes 276
|
||||||
#define TARGET_FREEBSD_NR_sigsuspend 341
|
#define TARGET_FREEBSD_NR_netbsd_msync 277
|
||||||
#define TARGET_FREEBSD_NR_freebsd4_sigaction 342
|
#define TARGET_FREEBSD_NR_nstat 278
|
||||||
#define TARGET_FREEBSD_NR_sigpending 343
|
#define TARGET_FREEBSD_NR_nfstat 279
|
||||||
#define TARGET_FREEBSD_NR_freebsd4_sigreturn 344
|
#define TARGET_FREEBSD_NR_nlstat 280
|
||||||
#define TARGET_FREEBSD_NR_sigtimedwait 345
|
#define TARGET_FREEBSD_NR_preadv 289
|
||||||
#define TARGET_FREEBSD_NR_sigwaitinfo 346
|
#define TARGET_FREEBSD_NR_pwritev 290
|
||||||
#define TARGET_FREEBSD_NR___acl_get_file 347
|
#define TARGET_FREEBSD_NR_freebsd4_fhstatfs 297
|
||||||
#define TARGET_FREEBSD_NR___acl_set_file 348
|
#define TARGET_FREEBSD_NR_fhopen 298
|
||||||
#define TARGET_FREEBSD_NR___acl_get_fd 349
|
#define TARGET_FREEBSD_NR_fhstat 299
|
||||||
#define TARGET_FREEBSD_NR___acl_set_fd 350
|
#define TARGET_FREEBSD_NR_modnext 300
|
||||||
#define TARGET_FREEBSD_NR___acl_delete_file 351
|
#define TARGET_FREEBSD_NR_modstat 301
|
||||||
#define TARGET_FREEBSD_NR___acl_delete_fd 352
|
#define TARGET_FREEBSD_NR_modfnext 302
|
||||||
#define TARGET_FREEBSD_NR___acl_aclcheck_file 353
|
#define TARGET_FREEBSD_NR_modfind 303
|
||||||
#define TARGET_FREEBSD_NR___acl_aclcheck_fd 354
|
#define TARGET_FREEBSD_NR_kldload 304
|
||||||
#define TARGET_FREEBSD_NR_extattrctl 355
|
#define TARGET_FREEBSD_NR_kldunload 305
|
||||||
#define TARGET_FREEBSD_NR_extattr_set_file 356
|
#define TARGET_FREEBSD_NR_kldfind 306
|
||||||
#define TARGET_FREEBSD_NR_extattr_get_file 357
|
#define TARGET_FREEBSD_NR_kldnext 307
|
||||||
#define TARGET_FREEBSD_NR_extattr_delete_file 358
|
#define TARGET_FREEBSD_NR_kldstat 308
|
||||||
#define TARGET_FREEBSD_NR_aio_waitcomplete 359
|
#define TARGET_FREEBSD_NR_kldfirstmod 309
|
||||||
#define TARGET_FREEBSD_NR_getresuid 360
|
#define TARGET_FREEBSD_NR_getsid 310
|
||||||
#define TARGET_FREEBSD_NR_getresgid 361
|
#define TARGET_FREEBSD_NR_setresuid 311
|
||||||
#define TARGET_FREEBSD_NR_kqueue 362
|
#define TARGET_FREEBSD_NR_setresgid 312
|
||||||
#define TARGET_FREEBSD_NR_kevent 363
|
/* 313 is obsolete signanosleep */
|
||||||
#define TARGET_FREEBSD_NR_extattr_set_fd 371
|
#define TARGET_FREEBSD_NR_aio_return 314
|
||||||
#define TARGET_FREEBSD_NR_extattr_get_fd 372
|
#define TARGET_FREEBSD_NR_aio_suspend 315
|
||||||
#define TARGET_FREEBSD_NR_extattr_delete_fd 373
|
#define TARGET_FREEBSD_NR_aio_cancel 316
|
||||||
#define TARGET_FREEBSD_NR___setugid 374
|
#define TARGET_FREEBSD_NR_aio_error 317
|
||||||
#define TARGET_FREEBSD_NR_nfsclnt 375
|
#define TARGET_FREEBSD_NR_oaio_read 318
|
||||||
#define TARGET_FREEBSD_NR_eaccess 376
|
#define TARGET_FREEBSD_NR_oaio_write 319
|
||||||
#define TARGET_FREEBSD_NR_nmount 378
|
#define TARGET_FREEBSD_NR_olio_listio 320
|
||||||
#define TARGET_FREEBSD_NR___mac_get_proc 384
|
#define TARGET_FREEBSD_NR_yield 321
|
||||||
#define TARGET_FREEBSD_NR___mac_set_proc 385
|
/* 322 is obsolete thr_sleep */
|
||||||
#define TARGET_FREEBSD_NR___mac_get_fd 386
|
/* 323 is obsolete thr_wakeup */
|
||||||
#define TARGET_FREEBSD_NR___mac_get_file 387
|
#define TARGET_FREEBSD_NR_mlockall 324
|
||||||
#define TARGET_FREEBSD_NR___mac_set_fd 388
|
#define TARGET_FREEBSD_NR_munlockall 325
|
||||||
#define TARGET_FREEBSD_NR___mac_set_file 389
|
#define TARGET_FREEBSD_NR___getcwd 326
|
||||||
#define TARGET_FREEBSD_NR_kenv 390
|
#define TARGET_FREEBSD_NR_sched_setparam 327
|
||||||
#define TARGET_FREEBSD_NR_lchflags 391
|
#define TARGET_FREEBSD_NR_sched_getparam 328
|
||||||
#define TARGET_FREEBSD_NR_uuidgen 392
|
#define TARGET_FREEBSD_NR_sched_setscheduler 329
|
||||||
#define TARGET_FREEBSD_NR_sendfile 393
|
#define TARGET_FREEBSD_NR_sched_getscheduler 330
|
||||||
#define TARGET_FREEBSD_NR_mac_syscall 394
|
#define TARGET_FREEBSD_NR_sched_yield 331
|
||||||
#define TARGET_FREEBSD_NR_getfsstat 395
|
#define TARGET_FREEBSD_NR_sched_get_priority_max 332
|
||||||
#define TARGET_FREEBSD_NR_statfs 396
|
#define TARGET_FREEBSD_NR_sched_get_priority_min 333
|
||||||
#define TARGET_FREEBSD_NR_fstatfs 397
|
#define TARGET_FREEBSD_NR_sched_rr_get_interval 334
|
||||||
#define TARGET_FREEBSD_NR_fhstatfs 398
|
#define TARGET_FREEBSD_NR_utrace 335
|
||||||
#define TARGET_FREEBSD_NR_ksem_close 400
|
#define TARGET_FREEBSD_NR_freebsd4_sendfile 336
|
||||||
#define TARGET_FREEBSD_NR_ksem_post 401
|
#define TARGET_FREEBSD_NR_kldsym 337
|
||||||
#define TARGET_FREEBSD_NR_ksem_wait 402
|
#define TARGET_FREEBSD_NR_jail 338
|
||||||
#define TARGET_FREEBSD_NR_ksem_trywait 403
|
#define TARGET_FREEBSD_NR_nnpfs_syscall 339
|
||||||
#define TARGET_FREEBSD_NR_ksem_init 404
|
#define TARGET_FREEBSD_NR_sigprocmask 340
|
||||||
#define TARGET_FREEBSD_NR_ksem_open 405
|
#define TARGET_FREEBSD_NR_sigsuspend 341
|
||||||
#define TARGET_FREEBSD_NR_ksem_unlink 406
|
#define TARGET_FREEBSD_NR_freebsd4_sigaction 342
|
||||||
#define TARGET_FREEBSD_NR_ksem_getvalue 407
|
#define TARGET_FREEBSD_NR_sigpending 343
|
||||||
#define TARGET_FREEBSD_NR_ksem_destroy 408
|
#define TARGET_FREEBSD_NR_freebsd4_sigreturn 344
|
||||||
#define TARGET_FREEBSD_NR___mac_get_pid 409
|
#define TARGET_FREEBSD_NR_sigtimedwait 345
|
||||||
#define TARGET_FREEBSD_NR___mac_get_link 410
|
#define TARGET_FREEBSD_NR_sigwaitinfo 346
|
||||||
#define TARGET_FREEBSD_NR___mac_set_link 411
|
#define TARGET_FREEBSD_NR___acl_get_file 347
|
||||||
#define TARGET_FREEBSD_NR_extattr_set_link 412
|
#define TARGET_FREEBSD_NR___acl_set_file 348
|
||||||
#define TARGET_FREEBSD_NR_extattr_get_link 413
|
#define TARGET_FREEBSD_NR___acl_get_fd 349
|
||||||
#define TARGET_FREEBSD_NR_extattr_delete_link 414
|
#define TARGET_FREEBSD_NR___acl_set_fd 350
|
||||||
#define TARGET_FREEBSD_NR___mac_execve 415
|
#define TARGET_FREEBSD_NR___acl_delete_file 351
|
||||||
#define TARGET_FREEBSD_NR_sigaction 416
|
#define TARGET_FREEBSD_NR___acl_delete_fd 352
|
||||||
#define TARGET_FREEBSD_NR_sigreturn 417
|
#define TARGET_FREEBSD_NR___acl_aclcheck_file 353
|
||||||
#define TARGET_FREEBSD_NR_getcontext 421
|
#define TARGET_FREEBSD_NR___acl_aclcheck_fd 354
|
||||||
#define TARGET_FREEBSD_NR_setcontext 422
|
#define TARGET_FREEBSD_NR_extattrctl 355
|
||||||
#define TARGET_FREEBSD_NR_swapcontext 423
|
#define TARGET_FREEBSD_NR_extattr_set_file 356
|
||||||
#define TARGET_FREEBSD_NR_swapoff 424
|
#define TARGET_FREEBSD_NR_extattr_get_file 357
|
||||||
#define TARGET_FREEBSD_NR___acl_get_link 425
|
#define TARGET_FREEBSD_NR_extattr_delete_file 358
|
||||||
#define TARGET_FREEBSD_NR___acl_set_link 426
|
#define TARGET_FREEBSD_NR_aio_waitcomplete 359
|
||||||
#define TARGET_FREEBSD_NR___acl_delete_link 427
|
#define TARGET_FREEBSD_NR_getresuid 360
|
||||||
#define TARGET_FREEBSD_NR___acl_aclcheck_link 428
|
#define TARGET_FREEBSD_NR_getresgid 361
|
||||||
#define TARGET_FREEBSD_NR_sigwait 429
|
#define TARGET_FREEBSD_NR_kqueue 362
|
||||||
#define TARGET_FREEBSD_NR_thr_create 430
|
#define TARGET_FREEBSD_NR_kevent 363
|
||||||
#define TARGET_FREEBSD_NR_thr_exit 431
|
#define TARGET_FREEBSD_NR_extattr_set_fd 371
|
||||||
#define TARGET_FREEBSD_NR_thr_self 432
|
#define TARGET_FREEBSD_NR_extattr_get_fd 372
|
||||||
#define TARGET_FREEBSD_NR_thr_kill 433
|
#define TARGET_FREEBSD_NR_extattr_delete_fd 373
|
||||||
#define TARGET_FREEBSD_NR__umtx_lock 434
|
#define TARGET_FREEBSD_NR___setugid 374
|
||||||
#define TARGET_FREEBSD_NR__umtx_unlock 435
|
#define TARGET_FREEBSD_NR_eaccess 376
|
||||||
#define TARGET_FREEBSD_NR_jail_attach 436
|
#define TARGET_FREEBSD_NR_afs3_syscall 377
|
||||||
#define TARGET_FREEBSD_NR_extattr_list_fd 437
|
#define TARGET_FREEBSD_NR_nmount 378
|
||||||
#define TARGET_FREEBSD_NR_extattr_list_file 438
|
#define TARGET_FREEBSD_NR___mac_get_proc 384
|
||||||
#define TARGET_FREEBSD_NR_extattr_list_link 439
|
#define TARGET_FREEBSD_NR___mac_set_proc 385
|
||||||
#define TARGET_FREEBSD_NR_ksem_timedwait 441
|
#define TARGET_FREEBSD_NR___mac_get_fd 386
|
||||||
#define TARGET_FREEBSD_NR_thr_suspend 442
|
#define TARGET_FREEBSD_NR___mac_get_file 387
|
||||||
#define TARGET_FREEBSD_NR_thr_wake 443
|
#define TARGET_FREEBSD_NR___mac_set_fd 388
|
||||||
#define TARGET_FREEBSD_NR_kldunloadf 444
|
#define TARGET_FREEBSD_NR___mac_set_file 389
|
||||||
#define TARGET_FREEBSD_NR_audit 445
|
#define TARGET_FREEBSD_NR_kenv 390
|
||||||
#define TARGET_FREEBSD_NR_auditon 446
|
#define TARGET_FREEBSD_NR_lchflags 391
|
||||||
#define TARGET_FREEBSD_NR_getauid 447
|
#define TARGET_FREEBSD_NR_uuidgen 392
|
||||||
#define TARGET_FREEBSD_NR_setauid 448
|
#define TARGET_FREEBSD_NR_sendfile 393
|
||||||
#define TARGET_FREEBSD_NR_getaudit 449
|
#define TARGET_FREEBSD_NR_mac_syscall 394
|
||||||
#define TARGET_FREEBSD_NR_setaudit 450
|
#define TARGET_FREEBSD_NR_getfsstat 395
|
||||||
#define TARGET_FREEBSD_NR_getaudit_addr 451
|
#define TARGET_FREEBSD_NR_statfs 396
|
||||||
#define TARGET_FREEBSD_NR_setaudit_addr 452
|
#define TARGET_FREEBSD_NR_fstatfs 397
|
||||||
#define TARGET_FREEBSD_NR_auditctl 453
|
#define TARGET_FREEBSD_NR_fhstatfs 398
|
||||||
#define TARGET_FREEBSD_NR__umtx_op 454
|
#define TARGET_FREEBSD_NR_ksem_close 400
|
||||||
#define TARGET_FREEBSD_NR_thr_new 455
|
#define TARGET_FREEBSD_NR_ksem_post 401
|
||||||
#define TARGET_FREEBSD_NR_sigqueue 456
|
#define TARGET_FREEBSD_NR_ksem_wait 402
|
||||||
#define TARGET_FREEBSD_NR_kmq_open 457
|
#define TARGET_FREEBSD_NR_ksem_trywait 403
|
||||||
#define TARGET_FREEBSD_NR_kmq_setattr 458
|
#define TARGET_FREEBSD_NR_ksem_init 404
|
||||||
#define TARGET_FREEBSD_NR_kmq_timedreceive 459
|
#define TARGET_FREEBSD_NR_ksem_open 405
|
||||||
#define TARGET_FREEBSD_NR_kmq_timedsend 460
|
#define TARGET_FREEBSD_NR_ksem_unlink 406
|
||||||
#define TARGET_FREEBSD_NR_kmq_notify 461
|
#define TARGET_FREEBSD_NR_ksem_getvalue 407
|
||||||
#define TARGET_FREEBSD_NR_kmq_unlink 462
|
#define TARGET_FREEBSD_NR_ksem_destroy 408
|
||||||
#define TARGET_FREEBSD_NR_abort2 463
|
#define TARGET_FREEBSD_NR___mac_get_pid 409
|
||||||
#define TARGET_FREEBSD_NR_thr_set_name 464
|
#define TARGET_FREEBSD_NR___mac_get_link 410
|
||||||
#define TARGET_FREEBSD_NR_aio_fsync 465
|
#define TARGET_FREEBSD_NR___mac_set_link 411
|
||||||
#define TARGET_FREEBSD_NR_rtprio_thread 466
|
#define TARGET_FREEBSD_NR_extattr_set_link 412
|
||||||
#define TARGET_FREEBSD_NR_sctp_peeloff 471
|
#define TARGET_FREEBSD_NR_extattr_get_link 413
|
||||||
#define TARGET_FREEBSD_NR_sctp_generic_sendmsg 472
|
#define TARGET_FREEBSD_NR_extattr_delete_link 414
|
||||||
#define TARGET_FREEBSD_NR_sctp_generic_sendmsg_iov 473
|
#define TARGET_FREEBSD_NR___mac_execve 415
|
||||||
#define TARGET_FREEBSD_NR_sctp_generic_recvmsg 474
|
#define TARGET_FREEBSD_NR_sigaction 416
|
||||||
#define TARGET_FREEBSD_NR_pread 475
|
#define TARGET_FREEBSD_NR_sigreturn 417
|
||||||
#define TARGET_FREEBSD_NR_pwrite 476
|
#define TARGET_FREEBSD_NR_getcontext 421
|
||||||
#define TARGET_FREEBSD_NR_mmap 477
|
#define TARGET_FREEBSD_NR_setcontext 422
|
||||||
#define TARGET_FREEBSD_NR_lseek 478
|
#define TARGET_FREEBSD_NR_swapcontext 423
|
||||||
#define TARGET_FREEBSD_NR_truncate 479
|
#define TARGET_FREEBSD_NR_swapoff 424
|
||||||
#define TARGET_FREEBSD_NR_ftruncate 480
|
#define TARGET_FREEBSD_NR___acl_get_link 425
|
||||||
#define TARGET_FREEBSD_NR_thr_kill2 481
|
#define TARGET_FREEBSD_NR___acl_set_link 426
|
||||||
#define TARGET_FREEBSD_NR_shm_open 482
|
#define TARGET_FREEBSD_NR___acl_delete_link 427
|
||||||
#define TARGET_FREEBSD_NR_shm_unlink 483
|
#define TARGET_FREEBSD_NR___acl_aclcheck_link 428
|
||||||
#define TARGET_FREEBSD_NR_cpuset 484
|
#define TARGET_FREEBSD_NR_sigwait 429
|
||||||
#define TARGET_FREEBSD_NR_cpuset_setid 485
|
#define TARGET_FREEBSD_NR_thr_create 430
|
||||||
#define TARGET_FREEBSD_NR_cpuset_getid 486
|
#define TARGET_FREEBSD_NR_thr_exit 431
|
||||||
#define TARGET_FREEBSD_NR_cpuset_getaffinity 487
|
#define TARGET_FREEBSD_NR_thr_self 432
|
||||||
#define TARGET_FREEBSD_NR_cpuset_setaffinity 488
|
#define TARGET_FREEBSD_NR_thr_kill 433
|
||||||
#define TARGET_FREEBSD_NR_faccessat 489
|
#define TARGET_FREEBSD_NR__umtx_lock 434
|
||||||
#define TARGET_FREEBSD_NR_fchmodat 490
|
#define TARGET_FREEBSD_NR__umtx_unlock 435
|
||||||
#define TARGET_FREEBSD_NR_fchownat 491
|
#define TARGET_FREEBSD_NR_jail_attach 436
|
||||||
#define TARGET_FREEBSD_NR_fexecve 492
|
#define TARGET_FREEBSD_NR_extattr_list_fd 437
|
||||||
#define TARGET_FREEBSD_NR_fstatat 493
|
#define TARGET_FREEBSD_NR_extattr_list_file 438
|
||||||
#define TARGET_FREEBSD_NR_futimesat 494
|
#define TARGET_FREEBSD_NR_extattr_list_link 439
|
||||||
#define TARGET_FREEBSD_NR_linkat 495
|
#define TARGET_FREEBSD_NR_ksem_timedwait 441
|
||||||
#define TARGET_FREEBSD_NR_mkdirat 496
|
#define TARGET_FREEBSD_NR_thr_suspend 442
|
||||||
#define TARGET_FREEBSD_NR_mkfifoat 497
|
#define TARGET_FREEBSD_NR_thr_wake 443
|
||||||
#define TARGET_FREEBSD_NR_mknodat 498
|
#define TARGET_FREEBSD_NR_kldunloadf 444
|
||||||
#define TARGET_FREEBSD_NR_openat 499
|
#define TARGET_FREEBSD_NR_audit 445
|
||||||
#define TARGET_FREEBSD_NR_readlinkat 500
|
#define TARGET_FREEBSD_NR_auditon 446
|
||||||
#define TARGET_FREEBSD_NR_renameat 501
|
#define TARGET_FREEBSD_NR_getauid 447
|
||||||
#define TARGET_FREEBSD_NR_symlinkat 502
|
#define TARGET_FREEBSD_NR_setauid 448
|
||||||
#define TARGET_FREEBSD_NR_unlinkat 503
|
#define TARGET_FREEBSD_NR_getaudit 449
|
||||||
#define TARGET_FREEBSD_NR_posix_openpt 504
|
#define TARGET_FREEBSD_NR_setaudit 450
|
||||||
|
#define TARGET_FREEBSD_NR_getaudit_addr 451
|
||||||
|
#define TARGET_FREEBSD_NR_setaudit_addr 452
|
||||||
|
#define TARGET_FREEBSD_NR_auditctl 453
|
||||||
|
#define TARGET_FREEBSD_NR__umtx_op 454
|
||||||
|
#define TARGET_FREEBSD_NR_thr_new 455
|
||||||
|
#define TARGET_FREEBSD_NR_sigqueue 456
|
||||||
|
#define TARGET_FREEBSD_NR_kmq_open 457
|
||||||
|
#define TARGET_FREEBSD_NR_kmq_setattr 458
|
||||||
|
#define TARGET_FREEBSD_NR_kmq_timedreceive 459
|
||||||
|
#define TARGET_FREEBSD_NR_kmq_timedsend 460
|
||||||
|
#define TARGET_FREEBSD_NR_kmq_notify 461
|
||||||
|
#define TARGET_FREEBSD_NR_kmq_unlink 462
|
||||||
|
#define TARGET_FREEBSD_NR_abort2 463
|
||||||
|
#define TARGET_FREEBSD_NR_thr_set_name 464
|
||||||
|
#define TARGET_FREEBSD_NR_aio_fsync 465
|
||||||
|
#define TARGET_FREEBSD_NR_rtprio_thread 466
|
||||||
|
#define TARGET_FREEBSD_NR_sctp_peeloff 471
|
||||||
|
#define TARGET_FREEBSD_NR_sctp_generic_sendmsg 472
|
||||||
|
#define TARGET_FREEBSD_NR_sctp_generic_sendmsg_iov 473
|
||||||
|
#define TARGET_FREEBSD_NR_sctp_generic_recvmsg 474
|
||||||
|
#define TARGET_FREEBSD_NR_pread 475
|
||||||
|
#define TARGET_FREEBSD_NR_pwrite 476
|
||||||
|
#define TARGET_FREEBSD_NR_mmap 477
|
||||||
|
#define TARGET_FREEBSD_NR_lseek 478
|
||||||
|
#define TARGET_FREEBSD_NR_truncate 479
|
||||||
|
#define TARGET_FREEBSD_NR_ftruncate 480
|
||||||
|
#define TARGET_FREEBSD_NR_thr_kill2 481
|
||||||
|
#define TARGET_FREEBSD_NR_shm_open 482
|
||||||
|
#define TARGET_FREEBSD_NR_shm_unlink 483
|
||||||
|
#define TARGET_FREEBSD_NR_cpuset 484
|
||||||
|
#define TARGET_FREEBSD_NR_cpuset_setid 485
|
||||||
|
#define TARGET_FREEBSD_NR_cpuset_getid 486
|
||||||
|
#define TARGET_FREEBSD_NR_cpuset_getaffinity 487
|
||||||
|
#define TARGET_FREEBSD_NR_cpuset_setaffinity 488
|
||||||
|
#define TARGET_FREEBSD_NR_faccessat 489
|
||||||
|
#define TARGET_FREEBSD_NR_fchmodat 490
|
||||||
|
#define TARGET_FREEBSD_NR_fchownat 491
|
||||||
|
#define TARGET_FREEBSD_NR_fexecve 492
|
||||||
|
#define TARGET_FREEBSD_NR_fstatat 493
|
||||||
|
#define TARGET_FREEBSD_NR_futimesat 494
|
||||||
|
#define TARGET_FREEBSD_NR_linkat 495
|
||||||
|
#define TARGET_FREEBSD_NR_mkdirat 496
|
||||||
|
#define TARGET_FREEBSD_NR_mkfifoat 497
|
||||||
|
#define TARGET_FREEBSD_NR_mknodat 498
|
||||||
|
#define TARGET_FREEBSD_NR_openat 499
|
||||||
|
#define TARGET_FREEBSD_NR_readlinkat 500
|
||||||
|
#define TARGET_FREEBSD_NR_renameat 501
|
||||||
|
#define TARGET_FREEBSD_NR_symlinkat 502
|
||||||
|
#define TARGET_FREEBSD_NR_unlinkat 503
|
||||||
|
#define TARGET_FREEBSD_NR_posix_openpt 504
|
||||||
|
#define TARGET_FREEBSD_NR_gssd_syscall 505
|
||||||
|
#define TARGET_FREEBSD_NR_jail_get 506
|
||||||
|
#define TARGET_FREEBSD_NR_jail_set 507
|
||||||
|
#define TARGET_FREEBSD_NR_jail_remove 508
|
||||||
|
#define TARGET_FREEBSD_NR_closefrom 509
|
||||||
|
#define TARGET_FREEBSD_NR___semctl 510
|
||||||
|
#define TARGET_FREEBSD_NR_msgctl 511
|
||||||
|
#define TARGET_FREEBSD_NR_shmctl 512
|
||||||
|
#define TARGET_FREEBSD_NR_lpathconf 513
|
||||||
|
#define TARGET_FREEBSD_NR_cap_new 514
|
||||||
|
#define TARGET_FREEBSD_NR_cap_getrights 515
|
||||||
|
#define TARGET_FREEBSD_NR_cap_enter 516
|
||||||
|
#define TARGET_FREEBSD_NR_cap_getmode 517
|
||||||
|
#define TARGET_FREEBSD_NR_pdfork 518
|
||||||
|
#define TARGET_FREEBSD_NR_pdkill 519
|
||||||
|
#define TARGET_FREEBSD_NR_pdgetpid 520
|
||||||
|
#define TARGET_FREEBSD_NR_pselect 522
|
||||||
|
#define TARGET_FREEBSD_NR_getloginclass 523
|
||||||
|
#define TARGET_FREEBSD_NR_setloginclass 524
|
||||||
|
#define TARGET_FREEBSD_NR_rctl_get_racct 525
|
||||||
|
#define TARGET_FREEBSD_NR_rctl_get_rules 526
|
||||||
|
#define TARGET_FREEBSD_NR_rctl_get_limits 527
|
||||||
|
#define TARGET_FREEBSD_NR_rctl_add_rule 528
|
||||||
|
#define TARGET_FREEBSD_NR_rctl_remove_rule 529
|
||||||
|
#define TARGET_FREEBSD_NR_posix_fallocate 530
|
||||||
|
#define TARGET_FREEBSD_NR_posix_fadvise 531
|
||||||
|
#define TARGET_FREEBSD_NR_MAXSYSCALL 532
|
||||||
|
|||||||
@@ -1004,7 +1004,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
#if defined(TARGET_I386)
|
#if defined(TARGET_I386)
|
||||||
env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
|
env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
|
||||||
env->hflags |= HF_PE_MASK;
|
env->hflags |= HF_PE_MASK | HF_CPL_MASK;
|
||||||
if (env->features[FEAT_1_EDX] & CPUID_SSE) {
|
if (env->features[FEAT_1_EDX] & CPUID_SSE) {
|
||||||
env->cr[4] |= CR4_OSFXSR_MASK;
|
env->cr[4] |= CR4_OSFXSR_MASK;
|
||||||
env->hflags |= HF_OSFXSR_MASK;
|
env->hflags |= HF_OSFXSR_MASK;
|
||||||
|
|||||||
@@ -74,66 +74,6 @@ void mmap_unlock(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void *bsd_vmalloc(size_t size)
|
|
||||||
{
|
|
||||||
void *p;
|
|
||||||
mmap_lock();
|
|
||||||
/* Use map and mark the pages as used. */
|
|
||||||
p = mmap(NULL, size, PROT_READ | PROT_WRITE,
|
|
||||||
MAP_PRIVATE | MAP_ANON, -1, 0);
|
|
||||||
|
|
||||||
if (h2g_valid(p)) {
|
|
||||||
/* Allocated region overlaps guest address space.
|
|
||||||
This may recurse. */
|
|
||||||
abi_ulong addr = h2g(p);
|
|
||||||
page_set_flags(addr & TARGET_PAGE_MASK, TARGET_PAGE_ALIGN(addr + size),
|
|
||||||
PAGE_RESERVED);
|
|
||||||
}
|
|
||||||
|
|
||||||
mmap_unlock();
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *g_malloc(size_t size)
|
|
||||||
{
|
|
||||||
char * p;
|
|
||||||
size += 16;
|
|
||||||
p = bsd_vmalloc(size);
|
|
||||||
*(size_t *)p = size;
|
|
||||||
return p + 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We use map, which is always zero initialized. */
|
|
||||||
void * g_malloc0(size_t size)
|
|
||||||
{
|
|
||||||
return g_malloc(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void g_free(void *ptr)
|
|
||||||
{
|
|
||||||
/* FIXME: We should unmark the reserved pages here. However this gets
|
|
||||||
complicated when one target page spans multiple host pages, so we
|
|
||||||
don't bother. */
|
|
||||||
size_t *p;
|
|
||||||
p = (size_t *)((char *)ptr - 16);
|
|
||||||
munmap(p, *p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *g_realloc(void *ptr, size_t size)
|
|
||||||
{
|
|
||||||
size_t old_size, copy;
|
|
||||||
void *new_ptr;
|
|
||||||
|
|
||||||
if (!ptr)
|
|
||||||
return g_malloc(size);
|
|
||||||
old_size = *(size_t *)((char *)ptr - 16);
|
|
||||||
copy = old_size < size ? old_size : size;
|
|
||||||
new_ptr = g_malloc(size);
|
|
||||||
memcpy(new_ptr, ptr, copy);
|
|
||||||
g_free(ptr);
|
|
||||||
return new_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NOTE: all the constants are the HOST ones, but addresses are target. */
|
/* NOTE: all the constants are the HOST ones, but addresses are target. */
|
||||||
int target_mprotect(abi_ulong start, abi_ulong len, int prot)
|
int target_mprotect(abi_ulong start, abi_ulong len, int prot)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,3 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* qemu bsd user mode definition
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
#ifndef QEMU_H
|
#ifndef QEMU_H
|
||||||
#define QEMU_H
|
#define QEMU_H
|
||||||
|
|
||||||
@@ -5,6 +21,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
#include "exec/cpu_ldst.h"
|
||||||
|
|
||||||
#undef DEBUG_REMAP
|
#undef DEBUG_REMAP
|
||||||
#ifdef DEBUG_REMAP
|
#ifdef DEBUG_REMAP
|
||||||
@@ -149,6 +166,16 @@ void fork_end(int child);
|
|||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
|
|
||||||
/* strace.c */
|
/* strace.c */
|
||||||
|
struct syscallname {
|
||||||
|
int nr;
|
||||||
|
const char *name;
|
||||||
|
const char *format;
|
||||||
|
void (*call)(const struct syscallname *,
|
||||||
|
abi_long, abi_long, abi_long,
|
||||||
|
abi_long, abi_long, abi_long);
|
||||||
|
void (*result)(const struct syscallname *, abi_long);
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
print_freebsd_syscall(int num,
|
print_freebsd_syscall(int num,
|
||||||
abi_long arg1, abi_long arg2, abi_long arg3,
|
abi_long arg1, abi_long arg2, abi_long arg3,
|
||||||
|
|||||||
@@ -1,37 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* System call tracing and debugging
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
|
#include <sys/ioccom.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "qemu.h"
|
#include "qemu.h"
|
||||||
|
|
||||||
int do_strace=0;
|
int do_strace;
|
||||||
|
|
||||||
struct syscallname {
|
|
||||||
int nr;
|
|
||||||
const char *name;
|
|
||||||
const char *format;
|
|
||||||
void (*call)(const struct syscallname *,
|
|
||||||
abi_long, abi_long, abi_long,
|
|
||||||
abi_long, abi_long, abi_long);
|
|
||||||
void (*result)(const struct syscallname *, abi_long);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility functions
|
* Utility functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void print_sysctl(const struct syscallname *name, abi_long arg1,
|
||||||
print_execve(const struct syscallname *name,
|
abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5,
|
||||||
abi_long arg1, abi_long arg2, abi_long arg3,
|
abi_long arg6)
|
||||||
abi_long arg4, abi_long arg5, abi_long arg6)
|
{
|
||||||
|
uint32_t i;
|
||||||
|
int32_t *namep;
|
||||||
|
|
||||||
|
gemu_log("%s({ ", name->name);
|
||||||
|
namep = lock_user(VERIFY_READ, arg1, sizeof(int32_t) * arg2, 1);
|
||||||
|
if (namep) {
|
||||||
|
int32_t *p = namep;
|
||||||
|
|
||||||
|
for (i = 0; i < (uint32_t)arg2; i++) {
|
||||||
|
gemu_log("%d ", tswap32(*p++));
|
||||||
|
}
|
||||||
|
unlock_user(namep, arg1, 0);
|
||||||
|
}
|
||||||
|
gemu_log("}, %u, 0x" TARGET_ABI_FMT_lx ", 0x" TARGET_ABI_FMT_lx ", 0x"
|
||||||
|
TARGET_ABI_FMT_lx ", 0x" TARGET_ABI_FMT_lx ")",
|
||||||
|
(uint32_t)arg2, arg3, arg4, arg5, arg6);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_execve(const struct syscallname *name, abi_long arg1,
|
||||||
|
abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5,
|
||||||
|
abi_long arg6)
|
||||||
{
|
{
|
||||||
abi_ulong arg_ptr_addr;
|
abi_ulong arg_ptr_addr;
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
if (!(s = lock_user_string(arg1)))
|
s = lock_user_string(arg1);
|
||||||
|
if (s == NULL) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
gemu_log("%s(\"%s\",{", name->name, s);
|
gemu_log("%s(\"%s\",{", name->name, s);
|
||||||
unlock_user(s, arg1, 0);
|
unlock_user(s, arg1, 0);
|
||||||
|
|
||||||
@@ -39,29 +73,48 @@ print_execve(const struct syscallname *name,
|
|||||||
abi_ulong *arg_ptr, arg_addr;
|
abi_ulong *arg_ptr, arg_addr;
|
||||||
|
|
||||||
arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1);
|
arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1);
|
||||||
if (!arg_ptr)
|
if (!arg_ptr) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
arg_addr = tswapl(*arg_ptr);
|
arg_addr = tswapl(*arg_ptr);
|
||||||
unlock_user(arg_ptr, arg_ptr_addr, 0);
|
unlock_user(arg_ptr, arg_ptr_addr, 0);
|
||||||
if (!arg_addr)
|
if (!arg_addr) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
if ((s = lock_user_string(arg_addr))) {
|
if ((s = lock_user_string(arg_addr))) {
|
||||||
gemu_log("\"%s\",", s);
|
gemu_log("\"%s\",", s);
|
||||||
unlock_user(s, arg_addr, 0);
|
unlock_user(s, arg_addr, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gemu_log("NULL})");
|
gemu_log("NULL})");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print_ioctl(const struct syscallname *name,
|
||||||
|
abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4,
|
||||||
|
abi_long arg5, abi_long arg6)
|
||||||
|
{
|
||||||
|
/* Decode the ioctl request */
|
||||||
|
gemu_log("%s(%d, 0x%0lx { IO%s%s GRP:0x%x('%c') CMD:%d LEN:%d }, 0x"
|
||||||
|
TARGET_ABI_FMT_lx ", ...)",
|
||||||
|
name->name,
|
||||||
|
(int)arg1,
|
||||||
|
(unsigned long)arg2,
|
||||||
|
arg2 & IOC_OUT ? "R" : "",
|
||||||
|
arg2 & IOC_IN ? "W" : "",
|
||||||
|
(unsigned)IOCGROUP(arg2),
|
||||||
|
isprint(IOCGROUP(arg2)) ? (char)IOCGROUP(arg2) : '?',
|
||||||
|
(int)arg2 & 0xFF,
|
||||||
|
(int)IOCPARM_LEN(arg2),
|
||||||
|
arg3);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Variants for the return value output function
|
* Variants for the return value output function
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void print_syscall_ret_addr(const struct syscallname *name, abi_long ret)
|
||||||
print_syscall_ret_addr(const struct syscallname *name, abi_long ret)
|
|
||||||
{
|
{
|
||||||
if( ret == -1 ) {
|
if (ret == -1) {
|
||||||
gemu_log(" = -1 errno=%d (%s)\n", errno, strerror(errno));
|
gemu_log(" = -1 errno=%d (%s)\n", errno, strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
|
gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
|
||||||
@@ -90,10 +143,9 @@ static const struct syscallname openbsd_scnames[] = {
|
|||||||
#include "openbsd/strace.list"
|
#include "openbsd/strace.list"
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void print_syscall(int num, const struct syscallname *scnames,
|
||||||
print_syscall(int num, const struct syscallname *scnames, unsigned int nscnames,
|
unsigned int nscnames, abi_long arg1, abi_long arg2, abi_long arg3,
|
||||||
abi_long arg1, abi_long arg2, abi_long arg3,
|
abi_long arg4, abi_long arg5, abi_long arg6)
|
||||||
abi_long arg4, abi_long arg5, abi_long arg6)
|
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
const char *format="%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ","
|
const char *format="%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ","
|
||||||
@@ -102,36 +154,37 @@ print_syscall(int num, const struct syscallname *scnames, unsigned int nscnames,
|
|||||||
|
|
||||||
gemu_log("%d ", getpid() );
|
gemu_log("%d ", getpid() );
|
||||||
|
|
||||||
for (i = 0; i < nscnames; i++)
|
for (i = 0; i < nscnames; i++) {
|
||||||
if (scnames[i].nr == num) {
|
if (scnames[i].nr == num) {
|
||||||
if (scnames[i].call != NULL) {
|
if (scnames[i].call != NULL) {
|
||||||
scnames[i].call(&scnames[i], arg1, arg2, arg3, arg4, arg5,
|
scnames[i].call(&scnames[i], arg1, arg2, arg3, arg4, arg5,
|
||||||
arg6);
|
arg6);
|
||||||
} else {
|
} else {
|
||||||
/* XXX: this format system is broken because it uses
|
/* XXX: this format system is broken because it uses
|
||||||
host types and host pointers for strings */
|
host types and host pointers for strings */
|
||||||
if (scnames[i].format != NULL)
|
if (scnames[i].format != NULL) {
|
||||||
format = scnames[i].format;
|
format = scnames[i].format;
|
||||||
gemu_log(format, scnames[i].name, arg1, arg2, arg3, arg4,
|
}
|
||||||
arg5, arg6);
|
gemu_log(format, scnames[i].name, arg1, arg2, arg3, arg4, arg5,
|
||||||
|
arg6);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
gemu_log("Unknown syscall %d\n", num);
|
gemu_log("Unknown syscall %d\n", num);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void print_syscall_ret(int num, abi_long ret,
|
||||||
print_syscall_ret(int num, abi_long ret, const struct syscallname *scnames,
|
const struct syscallname *scnames, unsigned int nscnames)
|
||||||
unsigned int nscnames)
|
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < nscnames; i++)
|
for (i = 0; i < nscnames; i++) {
|
||||||
if (scnames[i].nr == num) {
|
if (scnames[i].nr == num) {
|
||||||
if (scnames[i].result != NULL) {
|
if (scnames[i].result != NULL) {
|
||||||
scnames[i].result(&scnames[i], ret);
|
scnames[i].result(&scnames[i], ret);
|
||||||
} else {
|
} else {
|
||||||
if( ret < 0 ) {
|
if (ret < 0) {
|
||||||
gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n", -ret,
|
gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n", -ret,
|
||||||
strerror(-ret));
|
strerror(-ret));
|
||||||
} else {
|
} else {
|
||||||
@@ -140,52 +193,50 @@ print_syscall_ret(int num, abi_long ret, const struct syscallname *scnames,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The public interface to this module.
|
* The public interface to this module.
|
||||||
*/
|
*/
|
||||||
void
|
void print_freebsd_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3,
|
||||||
print_freebsd_syscall(int num,
|
abi_long arg4, abi_long arg5, abi_long arg6)
|
||||||
abi_long arg1, abi_long arg2, abi_long arg3,
|
|
||||||
abi_long arg4, abi_long arg5, abi_long arg6)
|
|
||||||
{
|
{
|
||||||
print_syscall(num, freebsd_scnames, ARRAY_SIZE(freebsd_scnames),
|
|
||||||
arg1, arg2, arg3, arg4, arg5, arg6);
|
print_syscall(num, freebsd_scnames, ARRAY_SIZE(freebsd_scnames), arg1, arg2,
|
||||||
|
arg3, arg4, arg5, arg6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void print_freebsd_syscall_ret(int num, abi_long ret)
|
||||||
print_freebsd_syscall_ret(int num, abi_long ret)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
print_syscall_ret(num, ret, freebsd_scnames, ARRAY_SIZE(freebsd_scnames));
|
print_syscall_ret(num, ret, freebsd_scnames, ARRAY_SIZE(freebsd_scnames));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void print_netbsd_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3,
|
||||||
print_netbsd_syscall(int num,
|
abi_long arg4, abi_long arg5, abi_long arg6)
|
||||||
abi_long arg1, abi_long arg2, abi_long arg3,
|
|
||||||
abi_long arg4, abi_long arg5, abi_long arg6)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
print_syscall(num, netbsd_scnames, ARRAY_SIZE(netbsd_scnames),
|
print_syscall(num, netbsd_scnames, ARRAY_SIZE(netbsd_scnames),
|
||||||
arg1, arg2, arg3, arg4, arg5, arg6);
|
arg1, arg2, arg3, arg4, arg5, arg6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void print_netbsd_syscall_ret(int num, abi_long ret)
|
||||||
print_netbsd_syscall_ret(int num, abi_long ret)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
print_syscall_ret(num, ret, netbsd_scnames, ARRAY_SIZE(netbsd_scnames));
|
print_syscall_ret(num, ret, netbsd_scnames, ARRAY_SIZE(netbsd_scnames));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void print_openbsd_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3,
|
||||||
print_openbsd_syscall(int num,
|
abi_long arg4, abi_long arg5, abi_long arg6)
|
||||||
abi_long arg1, abi_long arg2, abi_long arg3,
|
|
||||||
abi_long arg4, abi_long arg5, abi_long arg6)
|
|
||||||
{
|
{
|
||||||
print_syscall(num, openbsd_scnames, ARRAY_SIZE(openbsd_scnames),
|
|
||||||
arg1, arg2, arg3, arg4, arg5, arg6);
|
print_syscall(num, openbsd_scnames, ARRAY_SIZE(openbsd_scnames), arg1, arg2,
|
||||||
|
arg3, arg4, arg5, arg6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void print_openbsd_syscall_ret(int num, abi_long ret)
|
||||||
print_openbsd_syscall_ret(int num, abi_long ret)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
print_syscall_ret(num, ret, openbsd_scnames, ARRAY_SIZE(openbsd_scnames));
|
print_syscall_ret(num, ret, openbsd_scnames, ARRAY_SIZE(openbsd_scnames));
|
||||||
}
|
}
|
||||||
|
|||||||
119
configure
vendored
119
configure
vendored
@@ -3,6 +3,11 @@
|
|||||||
# qemu configure script (c) 2003 Fabrice Bellard
|
# qemu configure script (c) 2003 Fabrice Bellard
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# Unset some variables known to interfere with behavior of common tools,
|
||||||
|
# just as autoconf does.
|
||||||
|
CLICOLOR_FORCE= GREP_OPTIONS=
|
||||||
|
unset CLICOLOR_FORCE GREP_OPTIONS
|
||||||
|
|
||||||
# Temporary directory used for files created while
|
# Temporary directory used for files created while
|
||||||
# configure runs. Since it is in the build directory
|
# configure runs. Since it is in the build directory
|
||||||
# we can safely blow away any previous version of it
|
# we can safely blow away any previous version of it
|
||||||
@@ -182,6 +187,10 @@ path_of() {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
have_backend () {
|
||||||
|
echo "$trace_backends" | grep "$1" >/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
# default parameters
|
# default parameters
|
||||||
source_path=`dirname "$0"`
|
source_path=`dirname "$0"`
|
||||||
cpu=""
|
cpu=""
|
||||||
@@ -293,7 +302,7 @@ pkgversion=""
|
|||||||
pie=""
|
pie=""
|
||||||
zero_malloc=""
|
zero_malloc=""
|
||||||
qom_cast_debug="yes"
|
qom_cast_debug="yes"
|
||||||
trace_backend="nop"
|
trace_backends="nop"
|
||||||
trace_file="trace"
|
trace_file="trace"
|
||||||
spice=""
|
spice=""
|
||||||
rbd=""
|
rbd=""
|
||||||
@@ -302,8 +311,8 @@ libusb=""
|
|||||||
usb_redir=""
|
usb_redir=""
|
||||||
glx=""
|
glx=""
|
||||||
zlib="yes"
|
zlib="yes"
|
||||||
lzo="no"
|
lzo=""
|
||||||
snappy="no"
|
snappy=""
|
||||||
guest_agent=""
|
guest_agent=""
|
||||||
guest_agent_with_vss="no"
|
guest_agent_with_vss="no"
|
||||||
vss_win32_sdk=""
|
vss_win32_sdk=""
|
||||||
@@ -324,7 +333,7 @@ vte=""
|
|||||||
tpm="no"
|
tpm="no"
|
||||||
libssh2=""
|
libssh2=""
|
||||||
vhdx=""
|
vhdx=""
|
||||||
quorum="no"
|
quorum=""
|
||||||
|
|
||||||
# parse CC options first
|
# parse CC options first
|
||||||
for opt do
|
for opt do
|
||||||
@@ -537,6 +546,9 @@ fi
|
|||||||
|
|
||||||
# OS specific
|
# OS specific
|
||||||
|
|
||||||
|
# host *BSD for user mode
|
||||||
|
HOST_VARIANT_DIR=""
|
||||||
|
|
||||||
case $targetos in
|
case $targetos in
|
||||||
CYGWIN*)
|
CYGWIN*)
|
||||||
mingw32="yes"
|
mingw32="yes"
|
||||||
@@ -562,12 +574,14 @@ FreeBSD)
|
|||||||
# needed for kinfo_getvmmap(3) in libutil.h
|
# needed for kinfo_getvmmap(3) in libutil.h
|
||||||
LIBS="-lutil $LIBS"
|
LIBS="-lutil $LIBS"
|
||||||
netmap="" # enable netmap autodetect
|
netmap="" # enable netmap autodetect
|
||||||
|
HOST_VARIANT_DIR="freebsd"
|
||||||
;;
|
;;
|
||||||
DragonFly)
|
DragonFly)
|
||||||
bsd="yes"
|
bsd="yes"
|
||||||
make="${MAKE-gmake}"
|
make="${MAKE-gmake}"
|
||||||
audio_drv_list="oss"
|
audio_drv_list="oss"
|
||||||
audio_possible_drivers="oss sdl esd pa"
|
audio_possible_drivers="oss sdl esd pa"
|
||||||
|
HOST_VARIANT_DIR="dragonfly"
|
||||||
;;
|
;;
|
||||||
NetBSD)
|
NetBSD)
|
||||||
bsd="yes"
|
bsd="yes"
|
||||||
@@ -575,12 +589,14 @@ NetBSD)
|
|||||||
audio_drv_list="oss"
|
audio_drv_list="oss"
|
||||||
audio_possible_drivers="oss sdl esd"
|
audio_possible_drivers="oss sdl esd"
|
||||||
oss_lib="-lossaudio"
|
oss_lib="-lossaudio"
|
||||||
|
HOST_VARIANT_DIR="netbsd"
|
||||||
;;
|
;;
|
||||||
OpenBSD)
|
OpenBSD)
|
||||||
bsd="yes"
|
bsd="yes"
|
||||||
make="${MAKE-gmake}"
|
make="${MAKE-gmake}"
|
||||||
audio_drv_list="sdl"
|
audio_drv_list="sdl"
|
||||||
audio_possible_drivers="sdl esd"
|
audio_possible_drivers="sdl esd"
|
||||||
|
HOST_VARIANT_DIR="openbsd"
|
||||||
;;
|
;;
|
||||||
Darwin)
|
Darwin)
|
||||||
bsd="yes"
|
bsd="yes"
|
||||||
@@ -598,6 +614,7 @@ Darwin)
|
|||||||
# Disable attempts to use ObjectiveC features in os/object.h since they
|
# Disable attempts to use ObjectiveC features in os/object.h since they
|
||||||
# won't work when we're compiling with gcc as a C compiler.
|
# won't work when we're compiling with gcc as a C compiler.
|
||||||
QEMU_CFLAGS="-DOS_OBJECT_USE_OBJC=0 $QEMU_CFLAGS"
|
QEMU_CFLAGS="-DOS_OBJECT_USE_OBJC=0 $QEMU_CFLAGS"
|
||||||
|
HOST_VARIANT_DIR="darwin"
|
||||||
;;
|
;;
|
||||||
SunOS)
|
SunOS)
|
||||||
solaris="yes"
|
solaris="yes"
|
||||||
@@ -753,7 +770,10 @@ for opt do
|
|||||||
;;
|
;;
|
||||||
--target-list=*) target_list="$optarg"
|
--target-list=*) target_list="$optarg"
|
||||||
;;
|
;;
|
||||||
--enable-trace-backend=*) trace_backend="$optarg"
|
--enable-trace-backends=*) trace_backends="$optarg"
|
||||||
|
;;
|
||||||
|
# XXX: backwards compatibility
|
||||||
|
--enable-trace-backend=*) trace_backends="$optarg"
|
||||||
;;
|
;;
|
||||||
--with-trace-file=*) trace_file="$optarg"
|
--with-trace-file=*) trace_file="$optarg"
|
||||||
;;
|
;;
|
||||||
@@ -1030,8 +1050,12 @@ for opt do
|
|||||||
;;
|
;;
|
||||||
--disable-zlib-test) zlib="no"
|
--disable-zlib-test) zlib="no"
|
||||||
;;
|
;;
|
||||||
|
--disable-lzo) lzo="no"
|
||||||
|
;;
|
||||||
--enable-lzo) lzo="yes"
|
--enable-lzo) lzo="yes"
|
||||||
;;
|
;;
|
||||||
|
--disable-snappy) snappy="no"
|
||||||
|
;;
|
||||||
--enable-snappy) snappy="yes"
|
--enable-snappy) snappy="yes"
|
||||||
;;
|
;;
|
||||||
--enable-guest-agent) guest_agent="yes"
|
--enable-guest-agent) guest_agent="yes"
|
||||||
@@ -1320,7 +1344,7 @@ Advanced options (experts only):
|
|||||||
--disable-docs disable documentation build
|
--disable-docs disable documentation build
|
||||||
--disable-vhost-net disable vhost-net acceleration support
|
--disable-vhost-net disable vhost-net acceleration support
|
||||||
--enable-vhost-net enable vhost-net acceleration support
|
--enable-vhost-net enable vhost-net acceleration support
|
||||||
--enable-trace-backend=B Set trace backend
|
--enable-trace-backends=B Set trace backend
|
||||||
Available backends: $($python $source_path/scripts/tracetool.py --list-backends)
|
Available backends: $($python $source_path/scripts/tracetool.py --list-backends)
|
||||||
--with-trace-file=NAME Full PATH,NAME of file to store traces
|
--with-trace-file=NAME Full PATH,NAME of file to store traces
|
||||||
Default:trace-<pid>
|
Default:trace-<pid>
|
||||||
@@ -1729,13 +1753,14 @@ if test "$lzo" != "no" ; then
|
|||||||
int main(void) { lzo_version(); return 0; }
|
int main(void) { lzo_version(); return 0; }
|
||||||
EOF
|
EOF
|
||||||
if compile_prog "" "-llzo2" ; then
|
if compile_prog "" "-llzo2" ; then
|
||||||
:
|
libs_softmmu="$libs_softmmu -llzo2"
|
||||||
|
lzo="yes"
|
||||||
else
|
else
|
||||||
error_exit "lzo check failed" \
|
if test "$lzo" = "yes"; then
|
||||||
"Make sure to have the lzo libs and headers installed."
|
feature_not_found "liblzo2" "Install liblzo2 devel"
|
||||||
|
fi
|
||||||
|
lzo="no"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
libs_softmmu="$libs_softmmu -llzo2"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
##########################################
|
##########################################
|
||||||
@@ -1747,13 +1772,14 @@ if test "$snappy" != "no" ; then
|
|||||||
int main(void) { snappy_max_compressed_length(4096); return 0; }
|
int main(void) { snappy_max_compressed_length(4096); return 0; }
|
||||||
EOF
|
EOF
|
||||||
if compile_prog "" "-lsnappy" ; then
|
if compile_prog "" "-lsnappy" ; then
|
||||||
:
|
libs_softmmu="$libs_softmmu -lsnappy"
|
||||||
|
snappy="yes"
|
||||||
else
|
else
|
||||||
error_exit "snappy check failed" \
|
if test "$snappy" = "yes"; then
|
||||||
"Make sure to have the snappy libs and headers installed."
|
feature_not_found "libsnappy" "Install libsnappy devel"
|
||||||
|
fi
|
||||||
|
snappy="no"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
libs_softmmu="$libs_softmmu -lsnappy"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
##########################################
|
##########################################
|
||||||
@@ -1986,6 +2012,7 @@ fi
|
|||||||
|
|
||||||
if test "$gtk" != "no"; then
|
if test "$gtk" != "no"; then
|
||||||
gtkpackage="gtk+-$gtkabi"
|
gtkpackage="gtk+-$gtkabi"
|
||||||
|
gtkx11package="gtk+-x11-$gtkabi"
|
||||||
if test "$gtkabi" = "3.0" ; then
|
if test "$gtkabi" = "3.0" ; then
|
||||||
gtkversion="3.0.0"
|
gtkversion="3.0.0"
|
||||||
else
|
else
|
||||||
@@ -1994,6 +2021,9 @@ if test "$gtk" != "no"; then
|
|||||||
if $pkg_config --exists "$gtkpackage >= $gtkversion"; then
|
if $pkg_config --exists "$gtkpackage >= $gtkversion"; then
|
||||||
gtk_cflags=`$pkg_config --cflags $gtkpackage`
|
gtk_cflags=`$pkg_config --cflags $gtkpackage`
|
||||||
gtk_libs=`$pkg_config --libs $gtkpackage`
|
gtk_libs=`$pkg_config --libs $gtkpackage`
|
||||||
|
if $pkg_config --exists "$gtkx11package >= $gtkversion"; then
|
||||||
|
gtk_libs="$gtk_libs -lX11"
|
||||||
|
fi
|
||||||
libs_softmmu="$gtk_libs $libs_softmmu"
|
libs_softmmu="$gtk_libs $libs_softmmu"
|
||||||
gtk="yes"
|
gtk="yes"
|
||||||
elif test "$gtk" = "yes"; then
|
elif test "$gtk" = "yes"; then
|
||||||
@@ -2195,9 +2225,12 @@ if compile_prog "$quorum_tls_cflags" "$quorum_tls_libs" ; then
|
|||||||
libs_softmmu="$quorum_tls_libs $libs_softmmu"
|
libs_softmmu="$quorum_tls_libs $libs_softmmu"
|
||||||
libs_tools="$quorum_tls_libs $libs_softmmu"
|
libs_tools="$quorum_tls_libs $libs_softmmu"
|
||||||
QEMU_CFLAGS="$QEMU_CFLAGS $quorum_tls_cflags"
|
QEMU_CFLAGS="$QEMU_CFLAGS $quorum_tls_cflags"
|
||||||
|
quorum="yes"
|
||||||
else
|
else
|
||||||
echo "gnutls > 2.10.0 required to compile Quorum"
|
if test "$quorum" = "yes"; then
|
||||||
exit 1
|
feature_not_found "gnutls" "gnutls > 2.10.0 required to compile Quorum"
|
||||||
|
fi
|
||||||
|
quorum="no"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -3445,9 +3478,9 @@ EOF
|
|||||||
if compile_prog "" "" ; then
|
if compile_prog "" "" ; then
|
||||||
:
|
:
|
||||||
# we need pthread for static linking. use previous pthread test result
|
# we need pthread for static linking. use previous pthread test result
|
||||||
elif compile_prog "" "-lrt $pthread_lib" ; then
|
elif compile_prog "" "$pthread_lib -lrt" ; then
|
||||||
LIBS="-lrt $LIBS"
|
LIBS="$LIBS -lrt"
|
||||||
libs_qga="-lrt $libs_qga"
|
libs_qga="$libs_qga -lrt"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$darwin" != "yes" -a "$mingw32" != "yes" -a "$solaris" != yes -a \
|
if test "$darwin" != "yes" -a "$mingw32" != "yes" -a "$solaris" != yes -a \
|
||||||
@@ -3666,15 +3699,15 @@ fi
|
|||||||
##########################################
|
##########################################
|
||||||
# check if trace backend exists
|
# check if trace backend exists
|
||||||
|
|
||||||
$python "$source_path/scripts/tracetool.py" "--backend=$trace_backend" --check-backend > /dev/null 2> /dev/null
|
$python "$source_path/scripts/tracetool.py" "--backends=$trace_backends" --check-backends > /dev/null 2> /dev/null
|
||||||
if test "$?" -ne 0 ; then
|
if test "$?" -ne 0 ; then
|
||||||
error_exit "invalid trace backend" \
|
error_exit "invalid trace backends" \
|
||||||
"Please choose a supported trace backend."
|
"Please choose supported trace backends."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
##########################################
|
##########################################
|
||||||
# For 'ust' backend, test if ust headers are present
|
# For 'ust' backend, test if ust headers are present
|
||||||
if test "$trace_backend" = "ust"; then
|
if have_backend "ust"; then
|
||||||
cat > $TMPC << EOF
|
cat > $TMPC << EOF
|
||||||
#include <lttng/tracepoint.h>
|
#include <lttng/tracepoint.h>
|
||||||
int main(void) { return 0; }
|
int main(void) { return 0; }
|
||||||
@@ -3700,7 +3733,7 @@ fi
|
|||||||
|
|
||||||
##########################################
|
##########################################
|
||||||
# For 'dtrace' backend, test if 'dtrace' command is present
|
# For 'dtrace' backend, test if 'dtrace' command is present
|
||||||
if test "$trace_backend" = "dtrace"; then
|
if have_backend "dtrace"; then
|
||||||
if ! has 'dtrace' ; then
|
if ! has 'dtrace' ; then
|
||||||
error_exit "dtrace command is not found in PATH $PATH"
|
error_exit "dtrace command is not found in PATH $PATH"
|
||||||
fi
|
fi
|
||||||
@@ -4170,7 +4203,7 @@ echo "uuid support $uuid"
|
|||||||
echo "libcap-ng support $cap_ng"
|
echo "libcap-ng support $cap_ng"
|
||||||
echo "vhost-net support $vhost_net"
|
echo "vhost-net support $vhost_net"
|
||||||
echo "vhost-scsi support $vhost_scsi"
|
echo "vhost-scsi support $vhost_scsi"
|
||||||
echo "Trace backend $trace_backend"
|
echo "Trace backends $trace_backends"
|
||||||
if test "$trace_backend" = "simple"; then
|
if test "$trace_backend" = "simple"; then
|
||||||
echo "Trace output file $trace_file-<pid>"
|
echo "Trace output file $trace_file-<pid>"
|
||||||
fi
|
fi
|
||||||
@@ -4664,43 +4697,35 @@ if test "$tpm" = "yes"; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# use default implementation for tracing backend-specific routines
|
echo "TRACE_BACKENDS=$trace_backends" >> $config_host_mak
|
||||||
trace_default=yes
|
if have_backend "nop"; then
|
||||||
echo "TRACE_BACKEND=$trace_backend" >> $config_host_mak
|
|
||||||
if test "$trace_backend" = "nop"; then
|
|
||||||
echo "CONFIG_TRACE_NOP=y" >> $config_host_mak
|
echo "CONFIG_TRACE_NOP=y" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
if test "$trace_backend" = "simple"; then
|
if have_backend "simple"; then
|
||||||
echo "CONFIG_TRACE_SIMPLE=y" >> $config_host_mak
|
echo "CONFIG_TRACE_SIMPLE=y" >> $config_host_mak
|
||||||
trace_default=no
|
|
||||||
# Set the appropriate trace file.
|
# Set the appropriate trace file.
|
||||||
trace_file="\"$trace_file-\" FMT_pid"
|
trace_file="\"$trace_file-\" FMT_pid"
|
||||||
fi
|
fi
|
||||||
if test "$trace_backend" = "stderr"; then
|
if have_backend "stderr"; then
|
||||||
echo "CONFIG_TRACE_STDERR=y" >> $config_host_mak
|
echo "CONFIG_TRACE_STDERR=y" >> $config_host_mak
|
||||||
trace_default=no
|
|
||||||
fi
|
fi
|
||||||
if test "$trace_backend" = "ust"; then
|
if have_backend "ust"; then
|
||||||
echo "CONFIG_TRACE_UST=y" >> $config_host_mak
|
echo "CONFIG_TRACE_UST=y" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
if test "$trace_backend" = "dtrace"; then
|
if have_backend "dtrace"; then
|
||||||
echo "CONFIG_TRACE_DTRACE=y" >> $config_host_mak
|
echo "CONFIG_TRACE_DTRACE=y" >> $config_host_mak
|
||||||
if test "$trace_backend_stap" = "yes" ; then
|
if test "$trace_backend_stap" = "yes" ; then
|
||||||
echo "CONFIG_TRACE_SYSTEMTAP=y" >> $config_host_mak
|
echo "CONFIG_TRACE_SYSTEMTAP=y" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if test "$trace_backend" = "ftrace"; then
|
if have_backend "ftrace"; then
|
||||||
if test "$linux" = "yes" ; then
|
if test "$linux" = "yes" ; then
|
||||||
echo "CONFIG_TRACE_FTRACE=y" >> $config_host_mak
|
echo "CONFIG_TRACE_FTRACE=y" >> $config_host_mak
|
||||||
trace_default=no
|
|
||||||
else
|
else
|
||||||
feature_not_found "ftrace(trace backend)" "ftrace requires Linux"
|
feature_not_found "ftrace(trace backend)" "ftrace requires Linux"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak
|
echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak
|
||||||
if test "$trace_default" = "yes"; then
|
|
||||||
echo "CONFIG_TRACE_DEFAULT=y" >> $config_host_mak
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "$rdma" = "yes" ; then
|
if test "$rdma" = "yes" ; then
|
||||||
echo "CONFIG_RDMA=y" >> $config_host_mak
|
echo "CONFIG_RDMA=y" >> $config_host_mak
|
||||||
@@ -4930,6 +4955,12 @@ case "$target_name" in
|
|||||||
TARGET_ABI_DIR=ppc
|
TARGET_ABI_DIR=ppc
|
||||||
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
|
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
|
||||||
;;
|
;;
|
||||||
|
ppc64le)
|
||||||
|
TARGET_ARCH=ppc64
|
||||||
|
TARGET_BASE_ARCH=ppc
|
||||||
|
TARGET_ABI_DIR=ppc
|
||||||
|
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
|
||||||
|
;;
|
||||||
ppc64abi32)
|
ppc64abi32)
|
||||||
TARGET_ARCH=ppc64
|
TARGET_ARCH=ppc64
|
||||||
TARGET_BASE_ARCH=ppc
|
TARGET_BASE_ARCH=ppc
|
||||||
@@ -4982,6 +5013,9 @@ if [ "$TARGET_ABI_DIR" = "" ]; then
|
|||||||
TARGET_ABI_DIR=$TARGET_ARCH
|
TARGET_ABI_DIR=$TARGET_ARCH
|
||||||
fi
|
fi
|
||||||
echo "TARGET_ABI_DIR=$TARGET_ABI_DIR" >> $config_target_mak
|
echo "TARGET_ABI_DIR=$TARGET_ABI_DIR" >> $config_target_mak
|
||||||
|
if [ "$HOST_VARIANT_DIR" != "" ]; then
|
||||||
|
echo "HOST_VARIANT_DIR=$HOST_VARIANT_DIR" >> $config_target_mak
|
||||||
|
fi
|
||||||
case "$target_name" in
|
case "$target_name" in
|
||||||
i386|x86_64)
|
i386|x86_64)
|
||||||
if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then
|
if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then
|
||||||
@@ -5194,6 +5228,7 @@ for bios_file in \
|
|||||||
$source_path/pc-bios/*.dtb \
|
$source_path/pc-bios/*.dtb \
|
||||||
$source_path/pc-bios/*.img \
|
$source_path/pc-bios/*.img \
|
||||||
$source_path/pc-bios/openbios-* \
|
$source_path/pc-bios/openbios-* \
|
||||||
|
$source_path/pc-bios/u-boot.* \
|
||||||
$source_path/pc-bios/palcode-*
|
$source_path/pc-bios/palcode-*
|
||||||
do
|
do
|
||||||
FILES="$FILES pc-bios/`basename $bios_file`"
|
FILES="$FILES pc-bios/`basename $bios_file`"
|
||||||
|
|||||||
@@ -30,20 +30,14 @@ typedef struct {
|
|||||||
CoroutineAction action;
|
CoroutineAction action;
|
||||||
} CoroutineGThread;
|
} CoroutineGThread;
|
||||||
|
|
||||||
static GStaticMutex coroutine_lock = G_STATIC_MUTEX_INIT;
|
static CompatGMutex coroutine_lock;
|
||||||
|
static CompatGCond coroutine_cond;
|
||||||
|
|
||||||
/* GLib 2.31 and beyond deprecated various parts of the thread API,
|
/* GLib 2.31 and beyond deprecated various parts of the thread API,
|
||||||
* but the new interfaces are not available in older GLib versions
|
* but the new interfaces are not available in older GLib versions
|
||||||
* so we have to cope with both.
|
* so we have to cope with both.
|
||||||
*/
|
*/
|
||||||
#if GLIB_CHECK_VERSION(2, 31, 0)
|
#if GLIB_CHECK_VERSION(2, 31, 0)
|
||||||
/* Default zero-initialisation is sufficient for 2.31+ GCond */
|
|
||||||
static GCond the_coroutine_cond;
|
|
||||||
static GCond *coroutine_cond = &the_coroutine_cond;
|
|
||||||
static inline void init_coroutine_cond(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Awkwardly, the GPrivate API doesn't provide a way to update the
|
/* Awkwardly, the GPrivate API doesn't provide a way to update the
|
||||||
* GDestroyNotify handler for the coroutine key dynamically. So instead
|
* GDestroyNotify handler for the coroutine key dynamically. So instead
|
||||||
* we track whether or not the CoroutineGThread should be freed on
|
* we track whether or not the CoroutineGThread should be freed on
|
||||||
@@ -84,11 +78,6 @@ static inline GThread *create_thread(GThreadFunc func, gpointer data)
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
/* Handle older GLib versions */
|
/* Handle older GLib versions */
|
||||||
static GCond *coroutine_cond;
|
|
||||||
static inline void init_coroutine_cond(void)
|
|
||||||
{
|
|
||||||
coroutine_cond = g_cond_new();
|
|
||||||
}
|
|
||||||
|
|
||||||
static GStaticPrivate coroutine_key = G_STATIC_PRIVATE_INIT;
|
static GStaticPrivate coroutine_key = G_STATIC_PRIVATE_INIT;
|
||||||
|
|
||||||
@@ -120,22 +109,20 @@ static void __attribute__((constructor)) coroutine_init(void)
|
|||||||
g_thread_init(NULL);
|
g_thread_init(NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
init_coroutine_cond();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void coroutine_wait_runnable_locked(CoroutineGThread *co)
|
static void coroutine_wait_runnable_locked(CoroutineGThread *co)
|
||||||
{
|
{
|
||||||
while (!co->runnable) {
|
while (!co->runnable) {
|
||||||
g_cond_wait(coroutine_cond, g_static_mutex_get_mutex(&coroutine_lock));
|
g_cond_wait(&coroutine_cond, &coroutine_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void coroutine_wait_runnable(CoroutineGThread *co)
|
static void coroutine_wait_runnable(CoroutineGThread *co)
|
||||||
{
|
{
|
||||||
g_static_mutex_lock(&coroutine_lock);
|
g_mutex_lock(&coroutine_lock);
|
||||||
coroutine_wait_runnable_locked(co);
|
coroutine_wait_runnable_locked(co);
|
||||||
g_static_mutex_unlock(&coroutine_lock);
|
g_mutex_unlock(&coroutine_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gpointer coroutine_thread(gpointer opaque)
|
static gpointer coroutine_thread(gpointer opaque)
|
||||||
@@ -177,17 +164,17 @@ CoroutineAction qemu_coroutine_switch(Coroutine *from_,
|
|||||||
CoroutineGThread *from = DO_UPCAST(CoroutineGThread, base, from_);
|
CoroutineGThread *from = DO_UPCAST(CoroutineGThread, base, from_);
|
||||||
CoroutineGThread *to = DO_UPCAST(CoroutineGThread, base, to_);
|
CoroutineGThread *to = DO_UPCAST(CoroutineGThread, base, to_);
|
||||||
|
|
||||||
g_static_mutex_lock(&coroutine_lock);
|
g_mutex_lock(&coroutine_lock);
|
||||||
from->runnable = false;
|
from->runnable = false;
|
||||||
from->action = action;
|
from->action = action;
|
||||||
to->runnable = true;
|
to->runnable = true;
|
||||||
to->action = action;
|
to->action = action;
|
||||||
g_cond_broadcast(coroutine_cond);
|
g_cond_broadcast(&coroutine_cond);
|
||||||
|
|
||||||
if (action != COROUTINE_TERMINATE) {
|
if (action != COROUTINE_TERMINATE) {
|
||||||
coroutine_wait_runnable_locked(from);
|
coroutine_wait_runnable_locked(from);
|
||||||
}
|
}
|
||||||
g_static_mutex_unlock(&coroutine_lock);
|
g_mutex_unlock(&coroutine_lock);
|
||||||
return from->action;
|
return from->action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
cpus.c
2
cpus.c
@@ -347,7 +347,7 @@ void qtest_clock_warp(int64_t dest)
|
|||||||
assert(qtest_enabled());
|
assert(qtest_enabled());
|
||||||
while (clock < dest) {
|
while (clock < dest) {
|
||||||
int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
|
int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
|
||||||
int64_t warp = MIN(dest - clock, deadline);
|
int64_t warp = qemu_soonest_timeout(dest - clock, deadline);
|
||||||
seqlock_write_lock(&timers_state.vm_clock_seqlock);
|
seqlock_write_lock(&timers_state.vm_clock_seqlock);
|
||||||
qemu_icount_bias += warp;
|
qemu_icount_bias += warp;
|
||||||
seqlock_write_unlock(&timers_state.vm_clock_seqlock);
|
seqlock_write_unlock(&timers_state.vm_clock_seqlock);
|
||||||
|
|||||||
33
cputlb.c
33
cputlb.c
@@ -22,11 +22,13 @@
|
|||||||
#include "exec/exec-all.h"
|
#include "exec/exec-all.h"
|
||||||
#include "exec/memory.h"
|
#include "exec/memory.h"
|
||||||
#include "exec/address-spaces.h"
|
#include "exec/address-spaces.h"
|
||||||
|
#include "exec/cpu_ldst.h"
|
||||||
|
|
||||||
#include "exec/cputlb.h"
|
#include "exec/cputlb.h"
|
||||||
|
|
||||||
#include "exec/memory-internal.h"
|
#include "exec/memory-internal.h"
|
||||||
#include "exec/ram_addr.h"
|
#include "exec/ram_addr.h"
|
||||||
|
#include "tcg/tcg.h"
|
||||||
|
|
||||||
//#define DEBUG_TLB
|
//#define DEBUG_TLB
|
||||||
//#define DEBUG_TLB_CHECK
|
//#define DEBUG_TLB_CHECK
|
||||||
@@ -330,21 +332,36 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
|
|||||||
return qemu_ram_addr_from_host_nofail(p);
|
return qemu_ram_addr_from_host_nofail(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MMUSUFFIX _mmu
|
||||||
|
|
||||||
|
#define SHIFT 0
|
||||||
|
#include "softmmu_template.h"
|
||||||
|
|
||||||
|
#define SHIFT 1
|
||||||
|
#include "softmmu_template.h"
|
||||||
|
|
||||||
|
#define SHIFT 2
|
||||||
|
#include "softmmu_template.h"
|
||||||
|
|
||||||
|
#define SHIFT 3
|
||||||
|
#include "softmmu_template.h"
|
||||||
|
#undef MMUSUFFIX
|
||||||
|
|
||||||
#define MMUSUFFIX _cmmu
|
#define MMUSUFFIX _cmmu
|
||||||
#undef GETPC
|
#undef GETPC_ADJ
|
||||||
#define GETPC() ((uintptr_t)0)
|
#define GETPC_ADJ 0
|
||||||
|
#undef GETRA
|
||||||
|
#define GETRA() ((uintptr_t)0)
|
||||||
#define SOFTMMU_CODE_ACCESS
|
#define SOFTMMU_CODE_ACCESS
|
||||||
|
|
||||||
#define SHIFT 0
|
#define SHIFT 0
|
||||||
#include "exec/softmmu_template.h"
|
#include "softmmu_template.h"
|
||||||
|
|
||||||
#define SHIFT 1
|
#define SHIFT 1
|
||||||
#include "exec/softmmu_template.h"
|
#include "softmmu_template.h"
|
||||||
|
|
||||||
#define SHIFT 2
|
#define SHIFT 2
|
||||||
#include "exec/softmmu_template.h"
|
#include "softmmu_template.h"
|
||||||
|
|
||||||
#define SHIFT 3
|
#define SHIFT 3
|
||||||
#include "exec/softmmu_template.h"
|
#include "softmmu_template.h"
|
||||||
|
|
||||||
#undef env
|
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
# Default configuration for ppc-linux-user
|
# Default configuration for ppc-linux-user
|
||||||
|
CONFIG_LIBDECNUMBER=y
|
||||||
|
|||||||
@@ -49,3 +49,4 @@ CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
|
|||||||
CONFIG_MC146818RTC=y
|
CONFIG_MC146818RTC=y
|
||||||
CONFIG_ETSEC=y
|
CONFIG_ETSEC=y
|
||||||
CONFIG_ISA_TESTDEV=y
|
CONFIG_ISA_TESTDEV=y
|
||||||
|
CONFIG_LIBDECNUMBER=y
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
# Default configuration for ppc64-linux-user
|
# Default configuration for ppc64-linux-user
|
||||||
|
CONFIG_LIBDECNUMBER=y
|
||||||
|
|||||||
@@ -58,3 +58,4 @@ CONFIG_I82374=y
|
|||||||
CONFIG_I8257=y
|
CONFIG_I8257=y
|
||||||
CONFIG_MC146818RTC=y
|
CONFIG_MC146818RTC=y
|
||||||
CONFIG_ISA_TESTDEV=y
|
CONFIG_ISA_TESTDEV=y
|
||||||
|
CONFIG_LIBDECNUMBER=y
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
# Default configuration for ppc64abi32-linux-user
|
# Default configuration for ppc64abi32-linux-user
|
||||||
|
CONFIG_LIBDECNUMBER=y
|
||||||
|
|||||||
2
default-configs/ppc64le-linux-user.mak
Normal file
2
default-configs/ppc64le-linux-user.mak
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# Default configuration for ppc64le-linux-user
|
||||||
|
CONFIG_LIBDECNUMBER=y
|
||||||
@@ -16,3 +16,4 @@ CONFIG_I8259=y
|
|||||||
CONFIG_XILINX=y
|
CONFIG_XILINX=y
|
||||||
CONFIG_XILINX_ETHLITE=y
|
CONFIG_XILINX_ETHLITE=y
|
||||||
CONFIG_OPENPIC=y
|
CONFIG_OPENPIC=y
|
||||||
|
CONFIG_LIBDECNUMBER=y
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ DriveInfo *add_init_drive(const char *optstr)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
mc = MACHINE_GET_CLASS(current_machine);
|
mc = MACHINE_GET_CLASS(current_machine);
|
||||||
dinfo = drive_init(opts, mc->block_default_type);
|
dinfo = drive_new(opts, mc->block_default_type);
|
||||||
if (!dinfo) {
|
if (!dinfo) {
|
||||||
qemu_opts_del(opts);
|
qemu_opts_del(opts);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -76,6 +76,6 @@ void drive_hot_add(Monitor *mon, const QDict *qdict)
|
|||||||
|
|
||||||
err:
|
err:
|
||||||
if (dinfo) {
|
if (dinfo) {
|
||||||
drive_put_ref(dinfo);
|
drive_del(dinfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
disas.c
21
disas.c
@@ -191,7 +191,8 @@ static int print_insn_od_target(bfd_vma pc, disassemble_info *info)
|
|||||||
values:
|
values:
|
||||||
i386 - 1 means 16 bit code, 2 means 64 bit code
|
i386 - 1 means 16 bit code, 2 means 64 bit code
|
||||||
arm - bit 0 = thumb, bit 1 = reverse endian, bit 2 = A64
|
arm - bit 0 = thumb, bit 1 = reverse endian, bit 2 = A64
|
||||||
ppc - nonzero means little endian
|
ppc - bits 0:15 specify (optionally) the machine instruction set;
|
||||||
|
bit 16 indicates little endian.
|
||||||
other targets - unused
|
other targets - unused
|
||||||
*/
|
*/
|
||||||
void target_disas(FILE *out, CPUArchState *env, target_ulong code,
|
void target_disas(FILE *out, CPUArchState *env, target_ulong code,
|
||||||
@@ -251,11 +252,11 @@ void target_disas(FILE *out, CPUArchState *env, target_ulong code,
|
|||||||
s.info.mach = bfd_mach_sparc_v9b;
|
s.info.mach = bfd_mach_sparc_v9b;
|
||||||
#endif
|
#endif
|
||||||
#elif defined(TARGET_PPC)
|
#elif defined(TARGET_PPC)
|
||||||
if (flags >> 16) {
|
if ((flags >> 16) & 1) {
|
||||||
s.info.endian = BFD_ENDIAN_LITTLE;
|
s.info.endian = BFD_ENDIAN_LITTLE;
|
||||||
}
|
}
|
||||||
if (flags & 0xFFFF) {
|
if (flags & 0xFFFF) {
|
||||||
/* If we have a precise definitions of the instructions set, use it */
|
/* If we have a precise definition of the instruction set, use it. */
|
||||||
s.info.mach = flags & 0xFFFF;
|
s.info.mach = flags & 0xFFFF;
|
||||||
} else {
|
} else {
|
||||||
#ifdef TARGET_PPC64
|
#ifdef TARGET_PPC64
|
||||||
@@ -444,6 +445,8 @@ monitor_fprintf(FILE *stream, const char *fmt, ...)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Disassembler for the monitor.
|
||||||
|
See target_disas for a description of flags. */
|
||||||
void monitor_disas(Monitor *mon, CPUArchState *env,
|
void monitor_disas(Monitor *mon, CPUArchState *env,
|
||||||
target_ulong pc, int nb_insn, int is_physical, int flags)
|
target_ulong pc, int nb_insn, int is_physical, int flags)
|
||||||
{
|
{
|
||||||
@@ -484,11 +487,19 @@ void monitor_disas(Monitor *mon, CPUArchState *env,
|
|||||||
s.info.mach = bfd_mach_sparc_v9b;
|
s.info.mach = bfd_mach_sparc_v9b;
|
||||||
#endif
|
#endif
|
||||||
#elif defined(TARGET_PPC)
|
#elif defined(TARGET_PPC)
|
||||||
|
if (flags & 0xFFFF) {
|
||||||
|
/* If we have a precise definition of the instruction set, use it. */
|
||||||
|
s.info.mach = flags & 0xFFFF;
|
||||||
|
} else {
|
||||||
#ifdef TARGET_PPC64
|
#ifdef TARGET_PPC64
|
||||||
s.info.mach = bfd_mach_ppc64;
|
s.info.mach = bfd_mach_ppc64;
|
||||||
#else
|
#else
|
||||||
s.info.mach = bfd_mach_ppc;
|
s.info.mach = bfd_mach_ppc;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
if ((flags >> 16) & 1) {
|
||||||
|
s.info.endian = BFD_ENDIAN_LITTLE;
|
||||||
|
}
|
||||||
print_insn = print_insn_ppc;
|
print_insn = print_insn_ppc;
|
||||||
#elif defined(TARGET_M68K)
|
#elif defined(TARGET_M68K)
|
||||||
print_insn = print_insn_m68k;
|
print_insn = print_insn_m68k;
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ In ubuntu/debian:
|
|||||||
Configuring and building:
|
Configuring and building:
|
||||||
./configure --enable-smartcard && make
|
./configure --enable-smartcard && make
|
||||||
|
|
||||||
|
|
||||||
3. Using ccid-card-emulated with hardware
|
3. Using ccid-card-emulated with hardware
|
||||||
|
|
||||||
Assuming you have a working smartcard on the host with the current
|
Assuming you have a working smartcard on the host with the current
|
||||||
@@ -54,19 +55,55 @@ user, using NSS, qemu acts as another NSS client using ccid-card-emulated:
|
|||||||
|
|
||||||
qemu -usb -device usb-ccid -device ccid-card-emulated
|
qemu -usb -device usb-ccid -device ccid-card-emulated
|
||||||
|
|
||||||
4. Using ccid-card-emulated with certificates
|
|
||||||
|
|
||||||
You must create the certificates. This is a one time process. We use NSS
|
4. Using ccid-card-emulated with certificates stored in files
|
||||||
certificates:
|
|
||||||
|
|
||||||
certutil -d /etc/pki/nssdb -x -t "CT,CT,CT" -S -s "CN=cert1" -n cert1
|
You must create the CA and card certificates. This is a one time process.
|
||||||
|
We use NSS certificates:
|
||||||
|
|
||||||
|
mkdir fake-smartcard
|
||||||
|
cd fake-smartcard
|
||||||
|
certutil -N -d sql:$PWD
|
||||||
|
certutil -S -d sql:$PWD -s "CN=Fake Smart Card CA" -x -t TC,TC,TC -n fake-smartcard-ca
|
||||||
|
certutil -S -d sql:$PWD -t ,, -s "CN=John Doe" -n id-cert -c fake-smartcard-ca
|
||||||
|
certutil -S -d sql:$PWD -t ,, -s "CN=John Doe (signing)" --nsCertType smime -n signing-cert -c fake-smartcard-ca
|
||||||
|
certutil -S -d sql:$PWD -t ,, -s "CN=John Doe (encryption)" --nsCertType sslClient -n encryption-cert -c fake-smartcard-ca
|
||||||
|
|
||||||
Note: you must have exactly three certificates.
|
Note: you must have exactly three certificates.
|
||||||
|
|
||||||
Assuming the current user can access the certificates (use certutil -L to
|
You can use the emulated card type with the certificates backend:
|
||||||
verify), you can use the emulated card type with the certificates backend:
|
|
||||||
|
qemu -usb -device usb-ccid -device ccid-card-emulated,backend=certificates,db=sql:$PWD,cert1=id-cert,cert2=signing-cert,cert3=encryption-cert
|
||||||
|
|
||||||
|
To use the certificates in the guest, export the CA certificate:
|
||||||
|
|
||||||
|
certutil -L -r -d sql:$PWD -o fake-smartcard-ca.cer -n fake-smartcard-ca
|
||||||
|
|
||||||
|
and import it in the guest:
|
||||||
|
|
||||||
|
certutil -A -d /etc/pki/nssdb -i fake-smartcard-ca.cer -t TC,TC,TC -n fake-smartcard-ca
|
||||||
|
|
||||||
|
In a Linux guest you can then use the CoolKey PKCS #11 module to access
|
||||||
|
the card:
|
||||||
|
|
||||||
|
certutil -d /etc/pki/nssdb -L -h all
|
||||||
|
|
||||||
|
It will prompt you for the PIN (which is the password you assigned to the
|
||||||
|
certificate database early on), and then show you all three certificates
|
||||||
|
together with the manually imported CA cert:
|
||||||
|
|
||||||
|
Certificate Nickname Trust Attributes
|
||||||
|
fake-smartcard-ca CT,C,C
|
||||||
|
John Doe:CAC ID Certificate u,u,u
|
||||||
|
John Doe:CAC Email Signature Certificate u,u,u
|
||||||
|
John Doe:CAC Email Encryption Certificate u,u,u
|
||||||
|
|
||||||
|
If this does not happen, CoolKey is not installed or not registered with
|
||||||
|
NSS. Registration can be done from Firefox or the command line:
|
||||||
|
|
||||||
|
modutil -dbdir /etc/pki/nssdb -add "CAC Module" -libfile /usr/lib64/pkcs11/libcoolkeypk11.so
|
||||||
|
modutil -dbdir /etc/pki/nssdb -list
|
||||||
|
|
||||||
qemu -usb -device usb-ccid -device ccid-card-emulated,backend=certificates,cert1=cert1,cert2=cert2,cert3=cert3
|
|
||||||
|
|
||||||
5. Using ccid-card-passthru with client side hardware
|
5. Using ccid-card-passthru with client side hardware
|
||||||
|
|
||||||
@@ -74,15 +111,23 @@ on the host specify the ccid-card-passthru device with a suitable chardev:
|
|||||||
|
|
||||||
qemu -chardev socket,server,host=0.0.0.0,port=2001,id=ccid,nowait -usb -device usb-ccid -device ccid-card-passthru,chardev=ccid
|
qemu -chardev socket,server,host=0.0.0.0,port=2001,id=ccid,nowait -usb -device usb-ccid -device ccid-card-passthru,chardev=ccid
|
||||||
|
|
||||||
on the client run vscclient, built when you built the libcacard library:
|
on the client run vscclient, built when you built QEMU:
|
||||||
libcacard/vscclient <qemu-host> 2001
|
|
||||||
|
vscclient <qemu-host> 2001
|
||||||
|
|
||||||
|
|
||||||
6. Using ccid-card-passthru with client side certificates
|
6. Using ccid-card-passthru with client side certificates
|
||||||
|
|
||||||
Run qemu as per #5, and run vscclient as follows:
|
This case is not particularly useful, but you can use it to debug
|
||||||
(Note: vscclient command line interface is in a state of change)
|
your setup if #4 works but #5 does not.
|
||||||
|
|
||||||
|
Follow instructions as per #4, except run QEMU and vscclient as follows:
|
||||||
|
Run qemu as per #5, and run vscclient from the "fake-smartcard"
|
||||||
|
directory as follows:
|
||||||
|
|
||||||
|
qemu -chardev socket,server,host=0.0.0.0,port=2001,id=ccid,nowait -usb -device usb-ccid -device ccid-card-passthru,chardev=ccid
|
||||||
|
vscclient -e "db=\"sql:$PWD\" use_hw=no soft=(,Test,CAC,,id-cert,signing-cert,encryption-cert)" <qemu-host> 2001
|
||||||
|
|
||||||
libcacard/vscclient -e "db=\"/etc/pki/nssdb\" use_hw=no soft=(,Test,CAC,,cert1,cert2,cert3)" <qemu-host> 2001
|
|
||||||
|
|
||||||
7. Passthrough protocol scenario
|
7. Passthrough protocol scenario
|
||||||
|
|
||||||
@@ -126,10 +171,11 @@ kill/quit | | | |
|
|||||||
|
|
||||||
8. libcacard
|
8. libcacard
|
||||||
|
|
||||||
ccid-card-passthru and vscclient use libcacard as the card emulator.
|
Both ccid-card-emulated and vscclient use libcacard as the card emulator.
|
||||||
libcacard implements a completely virtual CAC (DoD standard for smart cards)
|
libcacard implements a completely virtual CAC (DoD standard for smart
|
||||||
compliant card and uses NSS to actually retrive certificates and do any
|
cards) compliant card and uses NSS to retrieve certificates and do
|
||||||
encryption using the backend (real reader + card or file backed certificates).
|
any encryption. The backend can then be a real reader and card, or
|
||||||
|
certificates stored in files.
|
||||||
|
|
||||||
For documentation of cac_card see README in libcacard subdirectory.
|
For documentation of the library see docs/libcacard.txt.
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ for debugging, profiling, and observing execution.
|
|||||||
|
|
||||||
1. Build with the 'simple' trace backend:
|
1. Build with the 'simple' trace backend:
|
||||||
|
|
||||||
./configure --enable-trace-backend=simple
|
./configure --enable-trace-backends=simple
|
||||||
make
|
make
|
||||||
|
|
||||||
2. Create a file with the events you want to trace:
|
2. Create a file with the events you want to trace:
|
||||||
@@ -142,7 +142,7 @@ script.
|
|||||||
The trace backend is chosen at configure time and only one trace backend can
|
The trace backend is chosen at configure time and only one trace backend can
|
||||||
be built into the binary:
|
be built into the binary:
|
||||||
|
|
||||||
./configure --trace-backend=simple
|
./configure --trace-backends=simple
|
||||||
|
|
||||||
For a list of supported trace backends, try ./configure --help or see below.
|
For a list of supported trace backends, try ./configure --help or see below.
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ which will return a dictionary containing:
|
|||||||
|
|
||||||
o A key named last-update, which contains the last stats update
|
o A key named last-update, which contains the last stats update
|
||||||
timestamp in seconds. Since this timestamp is generated by the host,
|
timestamp in seconds. Since this timestamp is generated by the host,
|
||||||
a buggy guest can't influence its value
|
a buggy guest can't influence its value. The value is 0 if the guest
|
||||||
|
has not updated the stats (yet).
|
||||||
|
|
||||||
It's also important to note the following:
|
It's also important to note the following:
|
||||||
|
|
||||||
@@ -49,7 +50,7 @@ It's also important to note the following:
|
|||||||
|
|
||||||
- Polling can be enabled even if the guest doesn't have stats support
|
- Polling can be enabled even if the guest doesn't have stats support
|
||||||
or the balloon driver wasn't loaded in the guest. If this is the case
|
or the balloon driver wasn't loaded in the guest. If this is the case
|
||||||
and stats are queried, an error will be returned
|
and stats are queried, last-update will be 0.
|
||||||
|
|
||||||
- The polling timer is only re-armed when the guest responds to the
|
- The polling timer is only re-armed when the guest responds to the
|
||||||
statistics request. This means that if a (buggy) guest doesn't ever
|
statistics request. This means that if a (buggy) guest doesn't ever
|
||||||
|
|||||||
363
dump.c
363
dump.c
@@ -36,9 +36,9 @@
|
|||||||
#define ELF_MACHINE_UNAME "Unknown"
|
#define ELF_MACHINE_UNAME "Unknown"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static uint16_t cpu_convert_to_target16(uint16_t val, int endian)
|
uint16_t cpu_to_dump16(DumpState *s, uint16_t val)
|
||||||
{
|
{
|
||||||
if (endian == ELFDATA2LSB) {
|
if (s->dump_info.d_endian == ELFDATA2LSB) {
|
||||||
val = cpu_to_le16(val);
|
val = cpu_to_le16(val);
|
||||||
} else {
|
} else {
|
||||||
val = cpu_to_be16(val);
|
val = cpu_to_be16(val);
|
||||||
@@ -47,9 +47,9 @@ static uint16_t cpu_convert_to_target16(uint16_t val, int endian)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t cpu_convert_to_target32(uint32_t val, int endian)
|
uint32_t cpu_to_dump32(DumpState *s, uint32_t val)
|
||||||
{
|
{
|
||||||
if (endian == ELFDATA2LSB) {
|
if (s->dump_info.d_endian == ELFDATA2LSB) {
|
||||||
val = cpu_to_le32(val);
|
val = cpu_to_le32(val);
|
||||||
} else {
|
} else {
|
||||||
val = cpu_to_be32(val);
|
val = cpu_to_be32(val);
|
||||||
@@ -58,9 +58,9 @@ static uint32_t cpu_convert_to_target32(uint32_t val, int endian)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t cpu_convert_to_target64(uint64_t val, int endian)
|
uint64_t cpu_to_dump64(DumpState *s, uint64_t val)
|
||||||
{
|
{
|
||||||
if (endian == ELFDATA2LSB) {
|
if (s->dump_info.d_endian == ELFDATA2LSB) {
|
||||||
val = cpu_to_le64(val);
|
val = cpu_to_le64(val);
|
||||||
} else {
|
} else {
|
||||||
val = cpu_to_be64(val);
|
val = cpu_to_be64(val);
|
||||||
@@ -69,38 +69,6 @@ static uint64_t cpu_convert_to_target64(uint64_t val, int endian)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct DumpState {
|
|
||||||
GuestPhysBlockList guest_phys_blocks;
|
|
||||||
ArchDumpInfo dump_info;
|
|
||||||
MemoryMappingList list;
|
|
||||||
uint16_t phdr_num;
|
|
||||||
uint32_t sh_info;
|
|
||||||
bool have_section;
|
|
||||||
bool resume;
|
|
||||||
ssize_t note_size;
|
|
||||||
hwaddr memory_offset;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
GuestPhysBlock *next_block;
|
|
||||||
ram_addr_t start;
|
|
||||||
bool has_filter;
|
|
||||||
int64_t begin;
|
|
||||||
int64_t length;
|
|
||||||
|
|
||||||
uint8_t *note_buf; /* buffer for notes */
|
|
||||||
size_t note_buf_offset; /* the writing place in note_buf */
|
|
||||||
uint32_t nr_cpus; /* number of guest's cpu */
|
|
||||||
size_t page_size; /* guest's page size */
|
|
||||||
uint32_t page_shift; /* guest's page shift */
|
|
||||||
uint64_t max_mapnr; /* the biggest guest's phys-mem's number */
|
|
||||||
size_t len_dump_bitmap; /* the size of the place used to store
|
|
||||||
dump_bitmap in vmcore */
|
|
||||||
off_t offset_dump_bitmap; /* offset of dump_bitmap part in vmcore */
|
|
||||||
off_t offset_page; /* offset of page part in vmcore */
|
|
||||||
size_t num_dumpable; /* number of page that can be dumped */
|
|
||||||
uint32_t flag_compress; /* indicate the compression format */
|
|
||||||
} DumpState;
|
|
||||||
|
|
||||||
static int dump_cleanup(DumpState *s)
|
static int dump_cleanup(DumpState *s)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -139,29 +107,25 @@ static int write_elf64_header(DumpState *s)
|
|||||||
{
|
{
|
||||||
Elf64_Ehdr elf_header;
|
Elf64_Ehdr elf_header;
|
||||||
int ret;
|
int ret;
|
||||||
int endian = s->dump_info.d_endian;
|
|
||||||
|
|
||||||
memset(&elf_header, 0, sizeof(Elf64_Ehdr));
|
memset(&elf_header, 0, sizeof(Elf64_Ehdr));
|
||||||
memcpy(&elf_header, ELFMAG, SELFMAG);
|
memcpy(&elf_header, ELFMAG, SELFMAG);
|
||||||
elf_header.e_ident[EI_CLASS] = ELFCLASS64;
|
elf_header.e_ident[EI_CLASS] = ELFCLASS64;
|
||||||
elf_header.e_ident[EI_DATA] = s->dump_info.d_endian;
|
elf_header.e_ident[EI_DATA] = s->dump_info.d_endian;
|
||||||
elf_header.e_ident[EI_VERSION] = EV_CURRENT;
|
elf_header.e_ident[EI_VERSION] = EV_CURRENT;
|
||||||
elf_header.e_type = cpu_convert_to_target16(ET_CORE, endian);
|
elf_header.e_type = cpu_to_dump16(s, ET_CORE);
|
||||||
elf_header.e_machine = cpu_convert_to_target16(s->dump_info.d_machine,
|
elf_header.e_machine = cpu_to_dump16(s, s->dump_info.d_machine);
|
||||||
endian);
|
elf_header.e_version = cpu_to_dump32(s, EV_CURRENT);
|
||||||
elf_header.e_version = cpu_convert_to_target32(EV_CURRENT, endian);
|
elf_header.e_ehsize = cpu_to_dump16(s, sizeof(elf_header));
|
||||||
elf_header.e_ehsize = cpu_convert_to_target16(sizeof(elf_header), endian);
|
elf_header.e_phoff = cpu_to_dump64(s, sizeof(Elf64_Ehdr));
|
||||||
elf_header.e_phoff = cpu_convert_to_target64(sizeof(Elf64_Ehdr), endian);
|
elf_header.e_phentsize = cpu_to_dump16(s, sizeof(Elf64_Phdr));
|
||||||
elf_header.e_phentsize = cpu_convert_to_target16(sizeof(Elf64_Phdr),
|
elf_header.e_phnum = cpu_to_dump16(s, s->phdr_num);
|
||||||
endian);
|
|
||||||
elf_header.e_phnum = cpu_convert_to_target16(s->phdr_num, endian);
|
|
||||||
if (s->have_section) {
|
if (s->have_section) {
|
||||||
uint64_t shoff = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) * s->sh_info;
|
uint64_t shoff = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) * s->sh_info;
|
||||||
|
|
||||||
elf_header.e_shoff = cpu_convert_to_target64(shoff, endian);
|
elf_header.e_shoff = cpu_to_dump64(s, shoff);
|
||||||
elf_header.e_shentsize = cpu_convert_to_target16(sizeof(Elf64_Shdr),
|
elf_header.e_shentsize = cpu_to_dump16(s, sizeof(Elf64_Shdr));
|
||||||
endian);
|
elf_header.e_shnum = cpu_to_dump16(s, 1);
|
||||||
elf_header.e_shnum = cpu_convert_to_target16(1, endian);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s);
|
ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s);
|
||||||
@@ -177,29 +141,25 @@ static int write_elf32_header(DumpState *s)
|
|||||||
{
|
{
|
||||||
Elf32_Ehdr elf_header;
|
Elf32_Ehdr elf_header;
|
||||||
int ret;
|
int ret;
|
||||||
int endian = s->dump_info.d_endian;
|
|
||||||
|
|
||||||
memset(&elf_header, 0, sizeof(Elf32_Ehdr));
|
memset(&elf_header, 0, sizeof(Elf32_Ehdr));
|
||||||
memcpy(&elf_header, ELFMAG, SELFMAG);
|
memcpy(&elf_header, ELFMAG, SELFMAG);
|
||||||
elf_header.e_ident[EI_CLASS] = ELFCLASS32;
|
elf_header.e_ident[EI_CLASS] = ELFCLASS32;
|
||||||
elf_header.e_ident[EI_DATA] = endian;
|
elf_header.e_ident[EI_DATA] = s->dump_info.d_endian;
|
||||||
elf_header.e_ident[EI_VERSION] = EV_CURRENT;
|
elf_header.e_ident[EI_VERSION] = EV_CURRENT;
|
||||||
elf_header.e_type = cpu_convert_to_target16(ET_CORE, endian);
|
elf_header.e_type = cpu_to_dump16(s, ET_CORE);
|
||||||
elf_header.e_machine = cpu_convert_to_target16(s->dump_info.d_machine,
|
elf_header.e_machine = cpu_to_dump16(s, s->dump_info.d_machine);
|
||||||
endian);
|
elf_header.e_version = cpu_to_dump32(s, EV_CURRENT);
|
||||||
elf_header.e_version = cpu_convert_to_target32(EV_CURRENT, endian);
|
elf_header.e_ehsize = cpu_to_dump16(s, sizeof(elf_header));
|
||||||
elf_header.e_ehsize = cpu_convert_to_target16(sizeof(elf_header), endian);
|
elf_header.e_phoff = cpu_to_dump32(s, sizeof(Elf32_Ehdr));
|
||||||
elf_header.e_phoff = cpu_convert_to_target32(sizeof(Elf32_Ehdr), endian);
|
elf_header.e_phentsize = cpu_to_dump16(s, sizeof(Elf32_Phdr));
|
||||||
elf_header.e_phentsize = cpu_convert_to_target16(sizeof(Elf32_Phdr),
|
elf_header.e_phnum = cpu_to_dump16(s, s->phdr_num);
|
||||||
endian);
|
|
||||||
elf_header.e_phnum = cpu_convert_to_target16(s->phdr_num, endian);
|
|
||||||
if (s->have_section) {
|
if (s->have_section) {
|
||||||
uint32_t shoff = sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr) * s->sh_info;
|
uint32_t shoff = sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr) * s->sh_info;
|
||||||
|
|
||||||
elf_header.e_shoff = cpu_convert_to_target32(shoff, endian);
|
elf_header.e_shoff = cpu_to_dump32(s, shoff);
|
||||||
elf_header.e_shentsize = cpu_convert_to_target16(sizeof(Elf32_Shdr),
|
elf_header.e_shentsize = cpu_to_dump16(s, sizeof(Elf32_Shdr));
|
||||||
endian);
|
elf_header.e_shnum = cpu_to_dump16(s, 1);
|
||||||
elf_header.e_shnum = cpu_convert_to_target16(1, endian);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s);
|
ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s);
|
||||||
@@ -217,15 +177,14 @@ static int write_elf64_load(DumpState *s, MemoryMapping *memory_mapping,
|
|||||||
{
|
{
|
||||||
Elf64_Phdr phdr;
|
Elf64_Phdr phdr;
|
||||||
int ret;
|
int ret;
|
||||||
int endian = s->dump_info.d_endian;
|
|
||||||
|
|
||||||
memset(&phdr, 0, sizeof(Elf64_Phdr));
|
memset(&phdr, 0, sizeof(Elf64_Phdr));
|
||||||
phdr.p_type = cpu_convert_to_target32(PT_LOAD, endian);
|
phdr.p_type = cpu_to_dump32(s, PT_LOAD);
|
||||||
phdr.p_offset = cpu_convert_to_target64(offset, endian);
|
phdr.p_offset = cpu_to_dump64(s, offset);
|
||||||
phdr.p_paddr = cpu_convert_to_target64(memory_mapping->phys_addr, endian);
|
phdr.p_paddr = cpu_to_dump64(s, memory_mapping->phys_addr);
|
||||||
phdr.p_filesz = cpu_convert_to_target64(filesz, endian);
|
phdr.p_filesz = cpu_to_dump64(s, filesz);
|
||||||
phdr.p_memsz = cpu_convert_to_target64(memory_mapping->length, endian);
|
phdr.p_memsz = cpu_to_dump64(s, memory_mapping->length);
|
||||||
phdr.p_vaddr = cpu_convert_to_target64(memory_mapping->virt_addr, endian);
|
phdr.p_vaddr = cpu_to_dump64(s, memory_mapping->virt_addr);
|
||||||
|
|
||||||
assert(memory_mapping->length >= filesz);
|
assert(memory_mapping->length >= filesz);
|
||||||
|
|
||||||
@@ -244,15 +203,14 @@ static int write_elf32_load(DumpState *s, MemoryMapping *memory_mapping,
|
|||||||
{
|
{
|
||||||
Elf32_Phdr phdr;
|
Elf32_Phdr phdr;
|
||||||
int ret;
|
int ret;
|
||||||
int endian = s->dump_info.d_endian;
|
|
||||||
|
|
||||||
memset(&phdr, 0, sizeof(Elf32_Phdr));
|
memset(&phdr, 0, sizeof(Elf32_Phdr));
|
||||||
phdr.p_type = cpu_convert_to_target32(PT_LOAD, endian);
|
phdr.p_type = cpu_to_dump32(s, PT_LOAD);
|
||||||
phdr.p_offset = cpu_convert_to_target32(offset, endian);
|
phdr.p_offset = cpu_to_dump32(s, offset);
|
||||||
phdr.p_paddr = cpu_convert_to_target32(memory_mapping->phys_addr, endian);
|
phdr.p_paddr = cpu_to_dump32(s, memory_mapping->phys_addr);
|
||||||
phdr.p_filesz = cpu_convert_to_target32(filesz, endian);
|
phdr.p_filesz = cpu_to_dump32(s, filesz);
|
||||||
phdr.p_memsz = cpu_convert_to_target32(memory_mapping->length, endian);
|
phdr.p_memsz = cpu_to_dump32(s, memory_mapping->length);
|
||||||
phdr.p_vaddr = cpu_convert_to_target32(memory_mapping->virt_addr, endian);
|
phdr.p_vaddr = cpu_to_dump32(s, memory_mapping->virt_addr);
|
||||||
|
|
||||||
assert(memory_mapping->length >= filesz);
|
assert(memory_mapping->length >= filesz);
|
||||||
|
|
||||||
@@ -268,16 +226,15 @@ static int write_elf32_load(DumpState *s, MemoryMapping *memory_mapping,
|
|||||||
static int write_elf64_note(DumpState *s)
|
static int write_elf64_note(DumpState *s)
|
||||||
{
|
{
|
||||||
Elf64_Phdr phdr;
|
Elf64_Phdr phdr;
|
||||||
int endian = s->dump_info.d_endian;
|
|
||||||
hwaddr begin = s->memory_offset - s->note_size;
|
hwaddr begin = s->memory_offset - s->note_size;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
memset(&phdr, 0, sizeof(Elf64_Phdr));
|
memset(&phdr, 0, sizeof(Elf64_Phdr));
|
||||||
phdr.p_type = cpu_convert_to_target32(PT_NOTE, endian);
|
phdr.p_type = cpu_to_dump32(s, PT_NOTE);
|
||||||
phdr.p_offset = cpu_convert_to_target64(begin, endian);
|
phdr.p_offset = cpu_to_dump64(s, begin);
|
||||||
phdr.p_paddr = 0;
|
phdr.p_paddr = 0;
|
||||||
phdr.p_filesz = cpu_convert_to_target64(s->note_size, endian);
|
phdr.p_filesz = cpu_to_dump64(s, s->note_size);
|
||||||
phdr.p_memsz = cpu_convert_to_target64(s->note_size, endian);
|
phdr.p_memsz = cpu_to_dump64(s, s->note_size);
|
||||||
phdr.p_vaddr = 0;
|
phdr.p_vaddr = 0;
|
||||||
|
|
||||||
ret = fd_write_vmcore(&phdr, sizeof(Elf64_Phdr), s);
|
ret = fd_write_vmcore(&phdr, sizeof(Elf64_Phdr), s);
|
||||||
@@ -324,15 +281,14 @@ static int write_elf32_note(DumpState *s)
|
|||||||
{
|
{
|
||||||
hwaddr begin = s->memory_offset - s->note_size;
|
hwaddr begin = s->memory_offset - s->note_size;
|
||||||
Elf32_Phdr phdr;
|
Elf32_Phdr phdr;
|
||||||
int endian = s->dump_info.d_endian;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
memset(&phdr, 0, sizeof(Elf32_Phdr));
|
memset(&phdr, 0, sizeof(Elf32_Phdr));
|
||||||
phdr.p_type = cpu_convert_to_target32(PT_NOTE, endian);
|
phdr.p_type = cpu_to_dump32(s, PT_NOTE);
|
||||||
phdr.p_offset = cpu_convert_to_target32(begin, endian);
|
phdr.p_offset = cpu_to_dump32(s, begin);
|
||||||
phdr.p_paddr = 0;
|
phdr.p_paddr = 0;
|
||||||
phdr.p_filesz = cpu_convert_to_target32(s->note_size, endian);
|
phdr.p_filesz = cpu_to_dump32(s, s->note_size);
|
||||||
phdr.p_memsz = cpu_convert_to_target32(s->note_size, endian);
|
phdr.p_memsz = cpu_to_dump32(s, s->note_size);
|
||||||
phdr.p_vaddr = 0;
|
phdr.p_vaddr = 0;
|
||||||
|
|
||||||
ret = fd_write_vmcore(&phdr, sizeof(Elf32_Phdr), s);
|
ret = fd_write_vmcore(&phdr, sizeof(Elf32_Phdr), s);
|
||||||
@@ -374,7 +330,6 @@ static int write_elf_section(DumpState *s, int type)
|
|||||||
{
|
{
|
||||||
Elf32_Shdr shdr32;
|
Elf32_Shdr shdr32;
|
||||||
Elf64_Shdr shdr64;
|
Elf64_Shdr shdr64;
|
||||||
int endian = s->dump_info.d_endian;
|
|
||||||
int shdr_size;
|
int shdr_size;
|
||||||
void *shdr;
|
void *shdr;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -382,12 +337,12 @@ static int write_elf_section(DumpState *s, int type)
|
|||||||
if (type == 0) {
|
if (type == 0) {
|
||||||
shdr_size = sizeof(Elf32_Shdr);
|
shdr_size = sizeof(Elf32_Shdr);
|
||||||
memset(&shdr32, 0, shdr_size);
|
memset(&shdr32, 0, shdr_size);
|
||||||
shdr32.sh_info = cpu_convert_to_target32(s->sh_info, endian);
|
shdr32.sh_info = cpu_to_dump32(s, s->sh_info);
|
||||||
shdr = &shdr32;
|
shdr = &shdr32;
|
||||||
} else {
|
} else {
|
||||||
shdr_size = sizeof(Elf64_Shdr);
|
shdr_size = sizeof(Elf64_Shdr);
|
||||||
memset(&shdr64, 0, shdr_size);
|
memset(&shdr64, 0, shdr_size);
|
||||||
shdr64.sh_info = cpu_convert_to_target32(s->sh_info, endian);
|
shdr64.sh_info = cpu_to_dump32(s, s->sh_info);
|
||||||
shdr = &shdr64;
|
shdr = &shdr64;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -711,27 +666,25 @@ static int create_vmcore(DumpState *s)
|
|||||||
|
|
||||||
static int write_start_flat_header(int fd)
|
static int write_start_flat_header(int fd)
|
||||||
{
|
{
|
||||||
uint8_t *buf;
|
MakedumpfileHeader *mh;
|
||||||
MakedumpfileHeader mh;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
memset(&mh, 0, sizeof(mh));
|
QEMU_BUILD_BUG_ON(sizeof *mh > MAX_SIZE_MDF_HEADER);
|
||||||
strncpy(mh.signature, MAKEDUMPFILE_SIGNATURE,
|
mh = g_malloc0(MAX_SIZE_MDF_HEADER);
|
||||||
strlen(MAKEDUMPFILE_SIGNATURE));
|
|
||||||
|
|
||||||
mh.type = cpu_to_be64(TYPE_FLAT_HEADER);
|
memcpy(mh->signature, MAKEDUMPFILE_SIGNATURE,
|
||||||
mh.version = cpu_to_be64(VERSION_FLAT_HEADER);
|
MIN(sizeof mh->signature, sizeof MAKEDUMPFILE_SIGNATURE));
|
||||||
|
|
||||||
buf = g_malloc0(MAX_SIZE_MDF_HEADER);
|
mh->type = cpu_to_be64(TYPE_FLAT_HEADER);
|
||||||
memcpy(buf, &mh, sizeof(mh));
|
mh->version = cpu_to_be64(VERSION_FLAT_HEADER);
|
||||||
|
|
||||||
size_t written_size;
|
size_t written_size;
|
||||||
written_size = qemu_write_full(fd, buf, MAX_SIZE_MDF_HEADER);
|
written_size = qemu_write_full(fd, mh, MAX_SIZE_MDF_HEADER);
|
||||||
if (written_size != MAX_SIZE_MDF_HEADER) {
|
if (written_size != MAX_SIZE_MDF_HEADER) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free(buf);
|
g_free(mh);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -795,7 +748,6 @@ static int create_header32(DumpState *s)
|
|||||||
DiskDumpHeader32 *dh = NULL;
|
DiskDumpHeader32 *dh = NULL;
|
||||||
KdumpSubHeader32 *kh = NULL;
|
KdumpSubHeader32 *kh = NULL;
|
||||||
size_t size;
|
size_t size;
|
||||||
int endian = s->dump_info.d_endian;
|
|
||||||
uint32_t block_size;
|
uint32_t block_size;
|
||||||
uint32_t sub_hdr_size;
|
uint32_t sub_hdr_size;
|
||||||
uint32_t bitmap_blocks;
|
uint32_t bitmap_blocks;
|
||||||
@@ -807,18 +759,17 @@ static int create_header32(DumpState *s)
|
|||||||
dh = g_malloc0(size);
|
dh = g_malloc0(size);
|
||||||
|
|
||||||
strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
|
strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
|
||||||
dh->header_version = cpu_convert_to_target32(6, endian);
|
dh->header_version = cpu_to_dump32(s, 6);
|
||||||
block_size = s->page_size;
|
block_size = TARGET_PAGE_SIZE;
|
||||||
dh->block_size = cpu_convert_to_target32(block_size, endian);
|
dh->block_size = cpu_to_dump32(s, block_size);
|
||||||
sub_hdr_size = sizeof(struct KdumpSubHeader32) + s->note_size;
|
sub_hdr_size = sizeof(struct KdumpSubHeader32) + s->note_size;
|
||||||
sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
|
sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
|
||||||
dh->sub_hdr_size = cpu_convert_to_target32(sub_hdr_size, endian);
|
dh->sub_hdr_size = cpu_to_dump32(s, sub_hdr_size);
|
||||||
/* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
|
/* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
|
||||||
dh->max_mapnr = cpu_convert_to_target32(MIN(s->max_mapnr, UINT_MAX),
|
dh->max_mapnr = cpu_to_dump32(s, MIN(s->max_mapnr, UINT_MAX));
|
||||||
endian);
|
dh->nr_cpus = cpu_to_dump32(s, s->nr_cpus);
|
||||||
dh->nr_cpus = cpu_convert_to_target32(s->nr_cpus, endian);
|
|
||||||
bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
|
bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
|
||||||
dh->bitmap_blocks = cpu_convert_to_target32(bitmap_blocks, endian);
|
dh->bitmap_blocks = cpu_to_dump32(s, bitmap_blocks);
|
||||||
strncpy(dh->utsname.machine, ELF_MACHINE_UNAME, sizeof(dh->utsname.machine));
|
strncpy(dh->utsname.machine, ELF_MACHINE_UNAME, sizeof(dh->utsname.machine));
|
||||||
|
|
||||||
if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
|
if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
|
||||||
@@ -834,7 +785,7 @@ static int create_header32(DumpState *s)
|
|||||||
status |= DUMP_DH_COMPRESSED_SNAPPY;
|
status |= DUMP_DH_COMPRESSED_SNAPPY;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
dh->status = cpu_convert_to_target32(status, endian);
|
dh->status = cpu_to_dump32(s, status);
|
||||||
|
|
||||||
if (write_buffer(s->fd, 0, dh, size) < 0) {
|
if (write_buffer(s->fd, 0, dh, size) < 0) {
|
||||||
dump_error(s, "dump: failed to write disk dump header.\n");
|
dump_error(s, "dump: failed to write disk dump header.\n");
|
||||||
@@ -847,13 +798,13 @@ static int create_header32(DumpState *s)
|
|||||||
kh = g_malloc0(size);
|
kh = g_malloc0(size);
|
||||||
|
|
||||||
/* 64bit max_mapnr_64 */
|
/* 64bit max_mapnr_64 */
|
||||||
kh->max_mapnr_64 = cpu_convert_to_target64(s->max_mapnr, endian);
|
kh->max_mapnr_64 = cpu_to_dump64(s, s->max_mapnr);
|
||||||
kh->phys_base = cpu_convert_to_target32(PHYS_BASE, endian);
|
kh->phys_base = cpu_to_dump32(s, PHYS_BASE);
|
||||||
kh->dump_level = cpu_convert_to_target32(DUMP_LEVEL, endian);
|
kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);
|
||||||
|
|
||||||
offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
|
offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
|
||||||
kh->offset_note = cpu_convert_to_target64(offset_note, endian);
|
kh->offset_note = cpu_to_dump64(s, offset_note);
|
||||||
kh->note_size = cpu_convert_to_target32(s->note_size, endian);
|
kh->note_size = cpu_to_dump32(s, s->note_size);
|
||||||
|
|
||||||
if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
|
if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
|
||||||
block_size, kh, size) < 0) {
|
block_size, kh, size) < 0) {
|
||||||
@@ -902,7 +853,6 @@ static int create_header64(DumpState *s)
|
|||||||
DiskDumpHeader64 *dh = NULL;
|
DiskDumpHeader64 *dh = NULL;
|
||||||
KdumpSubHeader64 *kh = NULL;
|
KdumpSubHeader64 *kh = NULL;
|
||||||
size_t size;
|
size_t size;
|
||||||
int endian = s->dump_info.d_endian;
|
|
||||||
uint32_t block_size;
|
uint32_t block_size;
|
||||||
uint32_t sub_hdr_size;
|
uint32_t sub_hdr_size;
|
||||||
uint32_t bitmap_blocks;
|
uint32_t bitmap_blocks;
|
||||||
@@ -914,18 +864,17 @@ static int create_header64(DumpState *s)
|
|||||||
dh = g_malloc0(size);
|
dh = g_malloc0(size);
|
||||||
|
|
||||||
strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
|
strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
|
||||||
dh->header_version = cpu_convert_to_target32(6, endian);
|
dh->header_version = cpu_to_dump32(s, 6);
|
||||||
block_size = s->page_size;
|
block_size = TARGET_PAGE_SIZE;
|
||||||
dh->block_size = cpu_convert_to_target32(block_size, endian);
|
dh->block_size = cpu_to_dump32(s, block_size);
|
||||||
sub_hdr_size = sizeof(struct KdumpSubHeader64) + s->note_size;
|
sub_hdr_size = sizeof(struct KdumpSubHeader64) + s->note_size;
|
||||||
sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
|
sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
|
||||||
dh->sub_hdr_size = cpu_convert_to_target32(sub_hdr_size, endian);
|
dh->sub_hdr_size = cpu_to_dump32(s, sub_hdr_size);
|
||||||
/* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
|
/* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
|
||||||
dh->max_mapnr = cpu_convert_to_target32(MIN(s->max_mapnr, UINT_MAX),
|
dh->max_mapnr = cpu_to_dump32(s, MIN(s->max_mapnr, UINT_MAX));
|
||||||
endian);
|
dh->nr_cpus = cpu_to_dump32(s, s->nr_cpus);
|
||||||
dh->nr_cpus = cpu_convert_to_target32(s->nr_cpus, endian);
|
|
||||||
bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
|
bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
|
||||||
dh->bitmap_blocks = cpu_convert_to_target32(bitmap_blocks, endian);
|
dh->bitmap_blocks = cpu_to_dump32(s, bitmap_blocks);
|
||||||
strncpy(dh->utsname.machine, ELF_MACHINE_UNAME, sizeof(dh->utsname.machine));
|
strncpy(dh->utsname.machine, ELF_MACHINE_UNAME, sizeof(dh->utsname.machine));
|
||||||
|
|
||||||
if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
|
if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
|
||||||
@@ -941,7 +890,7 @@ static int create_header64(DumpState *s)
|
|||||||
status |= DUMP_DH_COMPRESSED_SNAPPY;
|
status |= DUMP_DH_COMPRESSED_SNAPPY;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
dh->status = cpu_convert_to_target32(status, endian);
|
dh->status = cpu_to_dump32(s, status);
|
||||||
|
|
||||||
if (write_buffer(s->fd, 0, dh, size) < 0) {
|
if (write_buffer(s->fd, 0, dh, size) < 0) {
|
||||||
dump_error(s, "dump: failed to write disk dump header.\n");
|
dump_error(s, "dump: failed to write disk dump header.\n");
|
||||||
@@ -954,13 +903,13 @@ static int create_header64(DumpState *s)
|
|||||||
kh = g_malloc0(size);
|
kh = g_malloc0(size);
|
||||||
|
|
||||||
/* 64bit max_mapnr_64 */
|
/* 64bit max_mapnr_64 */
|
||||||
kh->max_mapnr_64 = cpu_convert_to_target64(s->max_mapnr, endian);
|
kh->max_mapnr_64 = cpu_to_dump64(s, s->max_mapnr);
|
||||||
kh->phys_base = cpu_convert_to_target64(PHYS_BASE, endian);
|
kh->phys_base = cpu_to_dump64(s, PHYS_BASE);
|
||||||
kh->dump_level = cpu_convert_to_target32(DUMP_LEVEL, endian);
|
kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);
|
||||||
|
|
||||||
offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
|
offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
|
||||||
kh->offset_note = cpu_convert_to_target64(offset_note, endian);
|
kh->offset_note = cpu_to_dump64(s, offset_note);
|
||||||
kh->note_size = cpu_convert_to_target64(s->note_size, endian);
|
kh->note_size = cpu_to_dump64(s, s->note_size);
|
||||||
|
|
||||||
if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
|
if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
|
||||||
block_size, kh, size) < 0) {
|
block_size, kh, size) < 0) {
|
||||||
@@ -1004,7 +953,7 @@ out:
|
|||||||
|
|
||||||
static int write_dump_header(DumpState *s)
|
static int write_dump_header(DumpState *s)
|
||||||
{
|
{
|
||||||
if (s->dump_info.d_machine == EM_386) {
|
if (s->dump_info.d_class == ELFCLASS32) {
|
||||||
return create_header32(s);
|
return create_header32(s);
|
||||||
} else {
|
} else {
|
||||||
return create_header64(s);
|
return create_header64(s);
|
||||||
@@ -1086,9 +1035,9 @@ static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr,
|
|||||||
if (!block) {
|
if (!block) {
|
||||||
block = QTAILQ_FIRST(&s->guest_phys_blocks.head);
|
block = QTAILQ_FIRST(&s->guest_phys_blocks.head);
|
||||||
*blockptr = block;
|
*blockptr = block;
|
||||||
assert(block->target_start % s->page_size == 0);
|
assert((block->target_start & ~TARGET_PAGE_MASK) == 0);
|
||||||
assert(block->target_end % s->page_size == 0);
|
assert((block->target_end & ~TARGET_PAGE_MASK) == 0);
|
||||||
*pfnptr = paddr_to_pfn(block->target_start, s->page_shift);
|
*pfnptr = paddr_to_pfn(block->target_start);
|
||||||
if (bufptr) {
|
if (bufptr) {
|
||||||
*bufptr = block->host_addr;
|
*bufptr = block->host_addr;
|
||||||
}
|
}
|
||||||
@@ -1096,10 +1045,10 @@ static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
*pfnptr = *pfnptr + 1;
|
*pfnptr = *pfnptr + 1;
|
||||||
addr = pfn_to_paddr(*pfnptr, s->page_shift);
|
addr = pfn_to_paddr(*pfnptr);
|
||||||
|
|
||||||
if ((addr >= block->target_start) &&
|
if ((addr >= block->target_start) &&
|
||||||
(addr + s->page_size <= block->target_end)) {
|
(addr + TARGET_PAGE_SIZE <= block->target_end)) {
|
||||||
buf = block->host_addr + (addr - block->target_start);
|
buf = block->host_addr + (addr - block->target_start);
|
||||||
} else {
|
} else {
|
||||||
/* the next page is in the next block */
|
/* the next page is in the next block */
|
||||||
@@ -1108,9 +1057,9 @@ static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr,
|
|||||||
if (!block) {
|
if (!block) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
assert(block->target_start % s->page_size == 0);
|
assert((block->target_start & ~TARGET_PAGE_MASK) == 0);
|
||||||
assert(block->target_end % s->page_size == 0);
|
assert((block->target_end & ~TARGET_PAGE_MASK) == 0);
|
||||||
*pfnptr = paddr_to_pfn(block->target_start, s->page_shift);
|
*pfnptr = paddr_to_pfn(block->target_start);
|
||||||
buf = block->host_addr;
|
buf = block->host_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1224,42 +1173,24 @@ static void free_data_cache(DataCache *data_cache)
|
|||||||
|
|
||||||
static size_t get_len_buf_out(size_t page_size, uint32_t flag_compress)
|
static size_t get_len_buf_out(size_t page_size, uint32_t flag_compress)
|
||||||
{
|
{
|
||||||
size_t len_buf_out_zlib, len_buf_out_lzo, len_buf_out_snappy;
|
switch (flag_compress) {
|
||||||
size_t len_buf_out;
|
case DUMP_DH_COMPRESSED_ZLIB:
|
||||||
|
return compressBound(page_size);
|
||||||
|
|
||||||
/* init buf_out */
|
case DUMP_DH_COMPRESSED_LZO:
|
||||||
len_buf_out_zlib = len_buf_out_lzo = len_buf_out_snappy = 0;
|
/*
|
||||||
|
* LZO will expand incompressible data by a little amount. Please check
|
||||||
/* buf size for zlib */
|
* the following URL to see the expansion calculation:
|
||||||
len_buf_out_zlib = compressBound(page_size);
|
* http://www.oberhumer.com/opensource/lzo/lzofaq.php
|
||||||
|
*/
|
||||||
/* buf size for lzo */
|
return page_size + page_size / 16 + 64 + 3;
|
||||||
#ifdef CONFIG_LZO
|
|
||||||
if (flag_compress & DUMP_DH_COMPRESSED_LZO) {
|
|
||||||
if (lzo_init() != LZO_E_OK) {
|
|
||||||
/* return 0 to indicate lzo is unavailable */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LZO will expand incompressible data by a little amount. please check the
|
|
||||||
* following URL to see the expansion calculation:
|
|
||||||
* http://www.oberhumer.com/opensource/lzo/lzofaq.php
|
|
||||||
*/
|
|
||||||
len_buf_out_lzo = page_size + page_size / 16 + 64 + 3;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_SNAPPY
|
#ifdef CONFIG_SNAPPY
|
||||||
/* buf size for snappy */
|
case DUMP_DH_COMPRESSED_SNAPPY:
|
||||||
len_buf_out_snappy = snappy_max_compressed_length(page_size);
|
return snappy_max_compressed_length(page_size);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
/* get the biggest that can store all kinds of compressed page */
|
return 0;
|
||||||
len_buf_out = MAX(len_buf_out_zlib,
|
|
||||||
MAX(len_buf_out_lzo, len_buf_out_snappy));
|
|
||||||
|
|
||||||
return len_buf_out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1282,7 +1213,6 @@ static int write_dump_pages(DumpState *s)
|
|||||||
off_t offset_desc, offset_data;
|
off_t offset_desc, offset_data;
|
||||||
PageDescriptor pd, pd_zero;
|
PageDescriptor pd, pd_zero;
|
||||||
uint8_t *buf;
|
uint8_t *buf;
|
||||||
int endian = s->dump_info.d_endian;
|
|
||||||
GuestPhysBlock *block_iter = NULL;
|
GuestPhysBlock *block_iter = NULL;
|
||||||
uint64_t pfn_iter;
|
uint64_t pfn_iter;
|
||||||
|
|
||||||
@@ -1294,11 +1224,8 @@ static int write_dump_pages(DumpState *s)
|
|||||||
prepare_data_cache(&page_data, s, offset_data);
|
prepare_data_cache(&page_data, s, offset_data);
|
||||||
|
|
||||||
/* prepare buffer to store compressed data */
|
/* prepare buffer to store compressed data */
|
||||||
len_buf_out = get_len_buf_out(s->page_size, s->flag_compress);
|
len_buf_out = get_len_buf_out(TARGET_PAGE_SIZE, s->flag_compress);
|
||||||
if (len_buf_out == 0) {
|
assert(len_buf_out != 0);
|
||||||
dump_error(s, "dump: failed to get length of output buffer.\n");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_LZO
|
#ifdef CONFIG_LZO
|
||||||
wrkmem = g_malloc(LZO1X_1_MEM_COMPRESS);
|
wrkmem = g_malloc(LZO1X_1_MEM_COMPRESS);
|
||||||
@@ -1310,19 +1237,19 @@ static int write_dump_pages(DumpState *s)
|
|||||||
* init zero page's page_desc and page_data, because every zero page
|
* init zero page's page_desc and page_data, because every zero page
|
||||||
* uses the same page_data
|
* uses the same page_data
|
||||||
*/
|
*/
|
||||||
pd_zero.size = cpu_convert_to_target32(s->page_size, endian);
|
pd_zero.size = cpu_to_dump32(s, TARGET_PAGE_SIZE);
|
||||||
pd_zero.flags = cpu_convert_to_target32(0, endian);
|
pd_zero.flags = cpu_to_dump32(s, 0);
|
||||||
pd_zero.offset = cpu_convert_to_target64(offset_data, endian);
|
pd_zero.offset = cpu_to_dump64(s, offset_data);
|
||||||
pd_zero.page_flags = cpu_convert_to_target64(0, endian);
|
pd_zero.page_flags = cpu_to_dump64(s, 0);
|
||||||
buf = g_malloc0(s->page_size);
|
buf = g_malloc0(TARGET_PAGE_SIZE);
|
||||||
ret = write_cache(&page_data, buf, s->page_size, false);
|
ret = write_cache(&page_data, buf, TARGET_PAGE_SIZE, false);
|
||||||
g_free(buf);
|
g_free(buf);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dump_error(s, "dump: failed to write page data(zero page).\n");
|
dump_error(s, "dump: failed to write page data(zero page).\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset_data += s->page_size;
|
offset_data += TARGET_PAGE_SIZE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dump memory to vmcore page by page. zero page will all be resided in the
|
* dump memory to vmcore page by page. zero page will all be resided in the
|
||||||
@@ -1330,7 +1257,7 @@ static int write_dump_pages(DumpState *s)
|
|||||||
*/
|
*/
|
||||||
while (get_next_page(&block_iter, &pfn_iter, &buf, s)) {
|
while (get_next_page(&block_iter, &pfn_iter, &buf, s)) {
|
||||||
/* check zero page */
|
/* check zero page */
|
||||||
if (is_zero_page(buf, s->page_size)) {
|
if (is_zero_page(buf, TARGET_PAGE_SIZE)) {
|
||||||
ret = write_cache(&page_desc, &pd_zero, sizeof(PageDescriptor),
|
ret = write_cache(&page_desc, &pd_zero, sizeof(PageDescriptor),
|
||||||
false);
|
false);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -1351,11 +1278,11 @@ static int write_dump_pages(DumpState *s)
|
|||||||
*/
|
*/
|
||||||
size_out = len_buf_out;
|
size_out = len_buf_out;
|
||||||
if ((s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) &&
|
if ((s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) &&
|
||||||
(compress2(buf_out, (uLongf *)&size_out, buf, s->page_size,
|
(compress2(buf_out, (uLongf *)&size_out, buf,
|
||||||
Z_BEST_SPEED) == Z_OK) && (size_out < s->page_size)) {
|
TARGET_PAGE_SIZE, Z_BEST_SPEED) == Z_OK) &&
|
||||||
pd.flags = cpu_convert_to_target32(DUMP_DH_COMPRESSED_ZLIB,
|
(size_out < TARGET_PAGE_SIZE)) {
|
||||||
endian);
|
pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_ZLIB);
|
||||||
pd.size = cpu_convert_to_target32(size_out, endian);
|
pd.size = cpu_to_dump32(s, size_out);
|
||||||
|
|
||||||
ret = write_cache(&page_data, buf_out, size_out, false);
|
ret = write_cache(&page_data, buf_out, size_out, false);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -1364,12 +1291,11 @@ static int write_dump_pages(DumpState *s)
|
|||||||
}
|
}
|
||||||
#ifdef CONFIG_LZO
|
#ifdef CONFIG_LZO
|
||||||
} else if ((s->flag_compress & DUMP_DH_COMPRESSED_LZO) &&
|
} else if ((s->flag_compress & DUMP_DH_COMPRESSED_LZO) &&
|
||||||
(lzo1x_1_compress(buf, s->page_size, buf_out,
|
(lzo1x_1_compress(buf, TARGET_PAGE_SIZE, buf_out,
|
||||||
(lzo_uint *)&size_out, wrkmem) == LZO_E_OK) &&
|
(lzo_uint *)&size_out, wrkmem) == LZO_E_OK) &&
|
||||||
(size_out < s->page_size)) {
|
(size_out < TARGET_PAGE_SIZE)) {
|
||||||
pd.flags = cpu_convert_to_target32(DUMP_DH_COMPRESSED_LZO,
|
pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_LZO);
|
||||||
endian);
|
pd.size = cpu_to_dump32(s, size_out);
|
||||||
pd.size = cpu_convert_to_target32(size_out, endian);
|
|
||||||
|
|
||||||
ret = write_cache(&page_data, buf_out, size_out, false);
|
ret = write_cache(&page_data, buf_out, size_out, false);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -1379,12 +1305,11 @@ static int write_dump_pages(DumpState *s)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SNAPPY
|
#ifdef CONFIG_SNAPPY
|
||||||
} else if ((s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) &&
|
} else if ((s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) &&
|
||||||
(snappy_compress((char *)buf, s->page_size,
|
(snappy_compress((char *)buf, TARGET_PAGE_SIZE,
|
||||||
(char *)buf_out, &size_out) == SNAPPY_OK) &&
|
(char *)buf_out, &size_out) == SNAPPY_OK) &&
|
||||||
(size_out < s->page_size)) {
|
(size_out < TARGET_PAGE_SIZE)) {
|
||||||
pd.flags = cpu_convert_to_target32(
|
pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_SNAPPY);
|
||||||
DUMP_DH_COMPRESSED_SNAPPY, endian);
|
pd.size = cpu_to_dump32(s, size_out);
|
||||||
pd.size = cpu_convert_to_target32(size_out, endian);
|
|
||||||
|
|
||||||
ret = write_cache(&page_data, buf_out, size_out, false);
|
ret = write_cache(&page_data, buf_out, size_out, false);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -1395,13 +1320,13 @@ static int write_dump_pages(DumpState *s)
|
|||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* fall back to save in plaintext, size_out should be
|
* fall back to save in plaintext, size_out should be
|
||||||
* assigned to s->page_size
|
* assigned TARGET_PAGE_SIZE
|
||||||
*/
|
*/
|
||||||
pd.flags = cpu_convert_to_target32(0, endian);
|
pd.flags = cpu_to_dump32(s, 0);
|
||||||
size_out = s->page_size;
|
size_out = TARGET_PAGE_SIZE;
|
||||||
pd.size = cpu_convert_to_target32(size_out, endian);
|
pd.size = cpu_to_dump32(s, size_out);
|
||||||
|
|
||||||
ret = write_cache(&page_data, buf, s->page_size, false);
|
ret = write_cache(&page_data, buf, TARGET_PAGE_SIZE, false);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dump_error(s, "dump: failed to write page data.\n");
|
dump_error(s, "dump: failed to write page data.\n");
|
||||||
goto out;
|
goto out;
|
||||||
@@ -1409,8 +1334,8 @@ static int write_dump_pages(DumpState *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get and write page desc here */
|
/* get and write page desc here */
|
||||||
pd.page_flags = cpu_convert_to_target64(0, endian);
|
pd.page_flags = cpu_to_dump64(s, 0);
|
||||||
pd.offset = cpu_convert_to_target64(offset_data, endian);
|
pd.offset = cpu_to_dump64(s, offset_data);
|
||||||
offset_data += size_out;
|
offset_data += size_out;
|
||||||
|
|
||||||
ret = write_cache(&page_desc, &pd, sizeof(PageDescriptor), false);
|
ret = write_cache(&page_desc, &pd, sizeof(PageDescriptor), false);
|
||||||
@@ -1536,7 +1461,7 @@ static void get_max_mapnr(DumpState *s)
|
|||||||
GuestPhysBlock *last_block;
|
GuestPhysBlock *last_block;
|
||||||
|
|
||||||
last_block = QTAILQ_LAST(&s->guest_phys_blocks.head, GuestPhysBlockHead);
|
last_block = QTAILQ_LAST(&s->guest_phys_blocks.head, GuestPhysBlockHead);
|
||||||
s->max_mapnr = paddr_to_pfn(last_block->target_end, s->page_shift);
|
s->max_mapnr = paddr_to_pfn(last_block->target_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dump_init(DumpState *s, int fd, bool has_format,
|
static int dump_init(DumpState *s, int fd, bool has_format,
|
||||||
@@ -1613,14 +1538,12 @@ static int dump_init(DumpState *s, int fd, bool has_format,
|
|||||||
}
|
}
|
||||||
|
|
||||||
s->nr_cpus = nr_cpus;
|
s->nr_cpus = nr_cpus;
|
||||||
s->page_size = TARGET_PAGE_SIZE;
|
|
||||||
s->page_shift = ffs(s->page_size) - 1;
|
|
||||||
|
|
||||||
get_max_mapnr(s);
|
get_max_mapnr(s);
|
||||||
|
|
||||||
uint64_t tmp;
|
uint64_t tmp;
|
||||||
tmp = DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT), s->page_size);
|
tmp = DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT), TARGET_PAGE_SIZE);
|
||||||
s->len_dump_bitmap = tmp * s->page_size;
|
s->len_dump_bitmap = tmp * TARGET_PAGE_SIZE;
|
||||||
|
|
||||||
/* init for kdump-compressed format */
|
/* init for kdump-compressed format */
|
||||||
if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
|
if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
|
||||||
@@ -1630,6 +1553,12 @@ static int dump_init(DumpState *s, int fd, bool has_format,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO:
|
case DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO:
|
||||||
|
#ifdef CONFIG_LZO
|
||||||
|
if (lzo_init() != LZO_E_OK) {
|
||||||
|
error_setg(errp, "failed to initialize the LZO library");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
s->flag_compress = DUMP_DH_COMPRESSED_LZO;
|
s->flag_compress = DUMP_DH_COMPRESSED_LZO;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
40
exec.c
40
exec.c
@@ -1201,17 +1201,24 @@ static void qemu_ram_setup_dump(void *addr, ram_addr_t size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
|
static RAMBlock *find_ram_block(ram_addr_t addr)
|
||||||
{
|
{
|
||||||
RAMBlock *new_block, *block;
|
RAMBlock *block;
|
||||||
|
|
||||||
new_block = NULL;
|
|
||||||
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
|
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
|
||||||
if (block->offset == addr) {
|
if (block->offset == addr) {
|
||||||
new_block = block;
|
return block;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
|
||||||
|
{
|
||||||
|
RAMBlock *new_block = find_ram_block(addr);
|
||||||
|
RAMBlock *block;
|
||||||
|
|
||||||
assert(new_block);
|
assert(new_block);
|
||||||
assert(!new_block->idstr[0]);
|
assert(!new_block->idstr[0]);
|
||||||
|
|
||||||
@@ -1236,6 +1243,15 @@ void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
|
|||||||
qemu_mutex_unlock_ramlist();
|
qemu_mutex_unlock_ramlist();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qemu_ram_unset_idstr(ram_addr_t addr)
|
||||||
|
{
|
||||||
|
RAMBlock *block = find_ram_block(addr);
|
||||||
|
|
||||||
|
if (block) {
|
||||||
|
memset(block->idstr, 0, sizeof(block->idstr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int memory_try_enable_merging(void *addr, size_t len)
|
static int memory_try_enable_merging(void *addr, size_t len)
|
||||||
{
|
{
|
||||||
if (!qemu_opt_get_bool(qemu_get_machine_opts(), "mem-merge", true)) {
|
if (!qemu_opt_get_bool(qemu_get_machine_opts(), "mem-merge", true)) {
|
||||||
@@ -1760,10 +1776,12 @@ static subpage_t *subpage_init(AddressSpace *as, hwaddr base)
|
|||||||
return mmio;
|
return mmio;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t dummy_section(PhysPageMap *map, MemoryRegion *mr)
|
static uint16_t dummy_section(PhysPageMap *map, AddressSpace *as,
|
||||||
|
MemoryRegion *mr)
|
||||||
{
|
{
|
||||||
|
assert(as);
|
||||||
MemoryRegionSection section = {
|
MemoryRegionSection section = {
|
||||||
.address_space = &address_space_memory,
|
.address_space = as,
|
||||||
.mr = mr,
|
.mr = mr,
|
||||||
.offset_within_address_space = 0,
|
.offset_within_address_space = 0,
|
||||||
.offset_within_region = 0,
|
.offset_within_region = 0,
|
||||||
@@ -1795,13 +1813,13 @@ static void mem_begin(MemoryListener *listener)
|
|||||||
AddressSpaceDispatch *d = g_new0(AddressSpaceDispatch, 1);
|
AddressSpaceDispatch *d = g_new0(AddressSpaceDispatch, 1);
|
||||||
uint16_t n;
|
uint16_t n;
|
||||||
|
|
||||||
n = dummy_section(&d->map, &io_mem_unassigned);
|
n = dummy_section(&d->map, as, &io_mem_unassigned);
|
||||||
assert(n == PHYS_SECTION_UNASSIGNED);
|
assert(n == PHYS_SECTION_UNASSIGNED);
|
||||||
n = dummy_section(&d->map, &io_mem_notdirty);
|
n = dummy_section(&d->map, as, &io_mem_notdirty);
|
||||||
assert(n == PHYS_SECTION_NOTDIRTY);
|
assert(n == PHYS_SECTION_NOTDIRTY);
|
||||||
n = dummy_section(&d->map, &io_mem_rom);
|
n = dummy_section(&d->map, as, &io_mem_rom);
|
||||||
assert(n == PHYS_SECTION_ROM);
|
assert(n == PHYS_SECTION_ROM);
|
||||||
n = dummy_section(&d->map, &io_mem_watch);
|
n = dummy_section(&d->map, as, &io_mem_watch);
|
||||||
assert(n == PHYS_SECTION_WATCH);
|
assert(n == PHYS_SECTION_WATCH);
|
||||||
|
|
||||||
d->phys_map = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .skip = 1 };
|
d->phys_map = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .skip = 1 };
|
||||||
|
|||||||
@@ -335,6 +335,7 @@ ETEXI
|
|||||||
.params = "tag|id",
|
.params = "tag|id",
|
||||||
.help = "restore a VM snapshot from its tag or id",
|
.help = "restore a VM snapshot from its tag or id",
|
||||||
.mhandler.cmd = do_loadvm,
|
.mhandler.cmd = do_loadvm,
|
||||||
|
.command_completion = loadvm_completion,
|
||||||
},
|
},
|
||||||
|
|
||||||
STEXI
|
STEXI
|
||||||
@@ -350,6 +351,7 @@ ETEXI
|
|||||||
.params = "tag|id",
|
.params = "tag|id",
|
||||||
.help = "delete a VM snapshot from its tag or id",
|
.help = "delete a VM snapshot from its tag or id",
|
||||||
.mhandler.cmd = do_delvm,
|
.mhandler.cmd = do_delvm,
|
||||||
|
.command_completion = delvm_completion,
|
||||||
},
|
},
|
||||||
|
|
||||||
STEXI
|
STEXI
|
||||||
@@ -852,6 +854,7 @@ ETEXI
|
|||||||
.params = "device data",
|
.params = "device data",
|
||||||
.help = "Write to a ring buffer character device",
|
.help = "Write to a ring buffer character device",
|
||||||
.mhandler.cmd = hmp_ringbuf_write,
|
.mhandler.cmd = hmp_ringbuf_write,
|
||||||
|
.command_completion = ringbuf_write_completion,
|
||||||
},
|
},
|
||||||
|
|
||||||
STEXI
|
STEXI
|
||||||
@@ -868,6 +871,7 @@ ETEXI
|
|||||||
.params = "device size",
|
.params = "device size",
|
||||||
.help = "Read from a ring buffer character device",
|
.help = "Read from a ring buffer character device",
|
||||||
.mhandler.cmd = hmp_ringbuf_read,
|
.mhandler.cmd = hmp_ringbuf_read,
|
||||||
|
.command_completion = ringbuf_write_completion,
|
||||||
},
|
},
|
||||||
|
|
||||||
STEXI
|
STEXI
|
||||||
@@ -973,6 +977,7 @@ ETEXI
|
|||||||
.params = "capability state",
|
.params = "capability state",
|
||||||
.help = "Enable/Disable the usage of a capability for migration",
|
.help = "Enable/Disable the usage of a capability for migration",
|
||||||
.mhandler.cmd = hmp_migrate_set_capability,
|
.mhandler.cmd = hmp_migrate_set_capability,
|
||||||
|
.command_completion = migrate_set_capability_completion,
|
||||||
},
|
},
|
||||||
|
|
||||||
STEXI
|
STEXI
|
||||||
@@ -1206,9 +1211,10 @@ ETEXI
|
|||||||
{
|
{
|
||||||
.name = "host_net_add",
|
.name = "host_net_add",
|
||||||
.args_type = "device:s,opts:s?",
|
.args_type = "device:s,opts:s?",
|
||||||
.params = "tap|user|socket|vde|netmap|dump [options]",
|
.params = "tap|user|socket|vde|netmap|bridge|dump [options]",
|
||||||
.help = "add host VLAN client",
|
.help = "add host VLAN client",
|
||||||
.mhandler.cmd = net_host_device_add,
|
.mhandler.cmd = net_host_device_add,
|
||||||
|
.command_completion = host_net_add_completion,
|
||||||
},
|
},
|
||||||
|
|
||||||
STEXI
|
STEXI
|
||||||
@@ -1223,6 +1229,7 @@ ETEXI
|
|||||||
.params = "vlan_id name",
|
.params = "vlan_id name",
|
||||||
.help = "remove host VLAN client",
|
.help = "remove host VLAN client",
|
||||||
.mhandler.cmd = net_host_device_remove,
|
.mhandler.cmd = net_host_device_remove,
|
||||||
|
.command_completion = host_net_remove_completion,
|
||||||
},
|
},
|
||||||
|
|
||||||
STEXI
|
STEXI
|
||||||
@@ -1357,6 +1364,7 @@ ETEXI
|
|||||||
.params = "[reset|shutdown|poweroff|pause|debug|none]",
|
.params = "[reset|shutdown|poweroff|pause|debug|none]",
|
||||||
.help = "change watchdog action",
|
.help = "change watchdog action",
|
||||||
.mhandler.cmd = do_watchdog_action,
|
.mhandler.cmd = do_watchdog_action,
|
||||||
|
.command_completion = watchdog_action_completion,
|
||||||
},
|
},
|
||||||
|
|
||||||
STEXI
|
STEXI
|
||||||
|
|||||||
11
hmp.h
11
hmp.h
@@ -103,5 +103,16 @@ void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str);
|
|||||||
void set_link_completion(ReadLineState *rs, int nb_args, const char *str);
|
void set_link_completion(ReadLineState *rs, int nb_args, const char *str);
|
||||||
void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str);
|
void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str);
|
||||||
void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str);
|
void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str);
|
||||||
|
void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str);
|
||||||
|
void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str);
|
||||||
|
void watchdog_action_completion(ReadLineState *rs, int nb_args,
|
||||||
|
const char *str);
|
||||||
|
void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
|
||||||
|
const char *str);
|
||||||
|
void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str);
|
||||||
|
void host_net_remove_completion(ReadLineState *rs, int nb_args,
|
||||||
|
const char *str);
|
||||||
|
void delvm_completion(ReadLineState *rs, int nb_args, const char *str);
|
||||||
|
void loadvm_completion(ReadLineState *rs, int nb_args, const char *str);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config)
|
|||||||
|
|
||||||
len = strlen(s->tag);
|
len = strlen(s->tag);
|
||||||
cfg = g_malloc0(sizeof(struct virtio_9p_config) + len);
|
cfg = g_malloc0(sizeof(struct virtio_9p_config) + len);
|
||||||
stw_raw(&cfg->tag_len, len);
|
stw_p(&cfg->tag_len, len);
|
||||||
/* We don't copy the terminating null to config space */
|
/* We don't copy the terminating null to config space */
|
||||||
memcpy(cfg->tag, s->tag, len);
|
memcpy(cfg->tag, s->tag, len);
|
||||||
memcpy(config, cfg, s->config_size);
|
memcpy(config, cfg, s->config_size);
|
||||||
|
|||||||
@@ -143,7 +143,6 @@ const VMStateDescription vmstate_ich9_pm = {
|
|||||||
.name = "ich9_pm",
|
.name = "ich9_pm",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.minimum_version_id_old = 1,
|
|
||||||
.post_load = ich9_pm_post_load,
|
.post_load = ich9_pm_post_load,
|
||||||
.fields = (VMStateField[]) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_UINT16(acpi_regs.pm1.evt.sts, ICH9LPCPMRegs),
|
VMSTATE_UINT16(acpi_regs.pm1.evt.sts, ICH9LPCPMRegs),
|
||||||
|
|||||||
@@ -324,8 +324,7 @@ const VMStateDescription vmstate_acpi_pcihp_pci_status = {
|
|||||||
.name = "acpi_pcihp_pci_status",
|
.name = "acpi_pcihp_pci_status",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.minimum_version_id_old = 1,
|
.fields = (VMStateField[]) {
|
||||||
.fields = (VMStateField []) {
|
|
||||||
VMSTATE_UINT32(up, AcpiPciHpPciStatus),
|
VMSTATE_UINT32(up, AcpiPciHpPciStatus),
|
||||||
VMSTATE_UINT32(down, AcpiPciHpPciStatus),
|
VMSTATE_UINT32(down, AcpiPciHpPciStatus),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
|
|||||||
@@ -177,8 +177,7 @@ static const VMStateDescription vmstate_gpe = {
|
|||||||
.name = "gpe",
|
.name = "gpe",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.minimum_version_id_old = 1,
|
.fields = (VMStateField[]) {
|
||||||
.fields = (VMStateField []) {
|
|
||||||
VMSTATE_GPE_ARRAY(sts, ACPIGPE),
|
VMSTATE_GPE_ARRAY(sts, ACPIGPE),
|
||||||
VMSTATE_GPE_ARRAY(en, ACPIGPE),
|
VMSTATE_GPE_ARRAY(en, ACPIGPE),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
@@ -189,8 +188,7 @@ static const VMStateDescription vmstate_pci_status = {
|
|||||||
.name = "pci_status",
|
.name = "pci_status",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.minimum_version_id_old = 1,
|
.fields = (VMStateField[]) {
|
||||||
.fields = (VMStateField []) {
|
|
||||||
VMSTATE_UINT32(up, struct AcpiPciHpPciStatus),
|
VMSTATE_UINT32(up, struct AcpiPciHpPciStatus),
|
||||||
VMSTATE_UINT32(down, struct AcpiPciHpPciStatus),
|
VMSTATE_UINT32(down, struct AcpiPciHpPciStatus),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
@@ -259,7 +257,7 @@ static const VMStateDescription vmstate_acpi = {
|
|||||||
.minimum_version_id_old = 1,
|
.minimum_version_id_old = 1,
|
||||||
.load_state_old = acpi_load_old,
|
.load_state_old = acpi_load_old,
|
||||||
.post_load = vmstate_acpi_post_load,
|
.post_load = vmstate_acpi_post_load,
|
||||||
.fields = (VMStateField []) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_PCI_DEVICE(parent_obj, PIIX4PMState),
|
VMSTATE_PCI_DEVICE(parent_obj, PIIX4PMState),
|
||||||
VMSTATE_UINT16(ar.pm1.evt.sts, PIIX4PMState),
|
VMSTATE_UINT16(ar.pm1.evt.sts, PIIX4PMState),
|
||||||
VMSTATE_UINT16(ar.pm1.evt.en, PIIX4PMState),
|
VMSTATE_UINT16(ar.pm1.evt.en, PIIX4PMState),
|
||||||
|
|||||||
316
hw/arm/nseries.c
316
hw/arm/nseries.c
@@ -239,8 +239,9 @@ static void n800_key_event(void *opaque, int keycode)
|
|||||||
int code = s->keymap[keycode & 0x7f];
|
int code = s->keymap[keycode & 0x7f];
|
||||||
|
|
||||||
if (code == -1) {
|
if (code == -1) {
|
||||||
if ((keycode & 0x7f) == RETU_KEYCODE)
|
if ((keycode & 0x7f) == RETU_KEYCODE) {
|
||||||
retu_key_event(s->retu, !(keycode & 0x80));
|
retu_key_event(s->retu, !(keycode & 0x80));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,11 +281,14 @@ static void n800_tsc_kbd_setup(struct n800_s *s)
|
|||||||
s->ts.opaque = s->ts.chip->opaque;
|
s->ts.opaque = s->ts.chip->opaque;
|
||||||
s->ts.txrx = tsc210x_txrx;
|
s->ts.txrx = tsc210x_txrx;
|
||||||
|
|
||||||
for (i = 0; i < 0x80; i ++)
|
for (i = 0; i < 0x80; i++) {
|
||||||
s->keymap[i] = -1;
|
s->keymap[i] = -1;
|
||||||
for (i = 0; i < 0x10; i ++)
|
}
|
||||||
if (n800_keys[i] >= 0)
|
for (i = 0; i < 0x10; i++) {
|
||||||
|
if (n800_keys[i] >= 0) {
|
||||||
s->keymap[n800_keys[i]] = i;
|
s->keymap[n800_keys[i]] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qemu_add_kbd_event_handler(n800_key_event, s);
|
qemu_add_kbd_event_handler(n800_key_event, s);
|
||||||
|
|
||||||
@@ -308,8 +312,9 @@ static void n810_key_event(void *opaque, int keycode)
|
|||||||
int code = s->keymap[keycode & 0x7f];
|
int code = s->keymap[keycode & 0x7f];
|
||||||
|
|
||||||
if (code == -1) {
|
if (code == -1) {
|
||||||
if ((keycode & 0x7f) == RETU_KEYCODE)
|
if ((keycode & 0x7f) == RETU_KEYCODE) {
|
||||||
retu_key_event(s->retu, !(keycode & 0x80));
|
retu_key_event(s->retu, !(keycode & 0x80));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,11 +393,14 @@ static void n810_kbd_setup(struct n800_s *s)
|
|||||||
qemu_irq kbd_irq = qdev_get_gpio_in(s->mpu->gpio, N810_KEYBOARD_GPIO);
|
qemu_irq kbd_irq = qdev_get_gpio_in(s->mpu->gpio, N810_KEYBOARD_GPIO);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 0x80; i ++)
|
for (i = 0; i < 0x80; i++) {
|
||||||
s->keymap[i] = -1;
|
s->keymap[i] = -1;
|
||||||
for (i = 0; i < 0x80; i ++)
|
}
|
||||||
if (n810_keys[i] > 0)
|
for (i = 0; i < 0x80; i++) {
|
||||||
|
if (n810_keys[i] > 0) {
|
||||||
s->keymap[n810_keys[i]] = i;
|
s->keymap[n810_keys[i]] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qemu_add_kbd_event_handler(n810_key_event, s);
|
qemu_add_kbd_event_handler(n810_key_event, s);
|
||||||
|
|
||||||
@@ -449,17 +457,20 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
|
|||||||
struct mipid_s *s = (struct mipid_s *) opaque;
|
struct mipid_s *s = (struct mipid_s *) opaque;
|
||||||
uint8_t ret;
|
uint8_t ret;
|
||||||
|
|
||||||
if (len > 9)
|
if (len > 9) {
|
||||||
hw_error("%s: FIXME: bad SPI word width %i\n", __FUNCTION__, len);
|
hw_error("%s: FIXME: bad SPI word width %i\n", __FUNCTION__, len);
|
||||||
|
}
|
||||||
|
|
||||||
if (s->p >= ARRAY_SIZE(s->resp))
|
if (s->p >= ARRAY_SIZE(s->resp)) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
else
|
} else {
|
||||||
ret = s->resp[s->p ++];
|
ret = s->resp[s->p++];
|
||||||
if (s->pm --> 0)
|
}
|
||||||
|
if (s->pm-- > 0) {
|
||||||
s->param[s->pm] = cmd;
|
s->param[s->pm] = cmd;
|
||||||
else
|
} else {
|
||||||
s->cmd = cmd;
|
s->cmd = cmd;
|
||||||
|
}
|
||||||
|
|
||||||
switch (s->cmd) {
|
switch (s->cmd) {
|
||||||
case 0x00: /* NOP */
|
case 0x00: /* NOP */
|
||||||
@@ -560,15 +571,17 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
|
|||||||
goto bad_cmd;
|
goto bad_cmd;
|
||||||
|
|
||||||
case 0x25: /* WRCNTR */
|
case 0x25: /* WRCNTR */
|
||||||
if (s->pm < 0)
|
if (s->pm < 0) {
|
||||||
s->pm = 1;
|
s->pm = 1;
|
||||||
|
}
|
||||||
goto bad_cmd;
|
goto bad_cmd;
|
||||||
|
|
||||||
case 0x26: /* GAMSET */
|
case 0x26: /* GAMSET */
|
||||||
if (!s->pm)
|
if (!s->pm) {
|
||||||
s->gamma = ffs(s->param[0] & 0xf) - 1;
|
s->gamma = ffs(s->param[0] & 0xf) - 1;
|
||||||
else if (s->pm < 0)
|
} else if (s->pm < 0) {
|
||||||
s->pm = 1;
|
s->pm = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x28: /* DISPOFF */
|
case 0x28: /* DISPOFF */
|
||||||
@@ -591,10 +604,11 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
|
|||||||
s->te = 0;
|
s->te = 0;
|
||||||
break;
|
break;
|
||||||
case 0x35: /* TEON */
|
case 0x35: /* TEON */
|
||||||
if (!s->pm)
|
if (!s->pm) {
|
||||||
s->te = 1;
|
s->te = 1;
|
||||||
else if (s->pm < 0)
|
} else if (s->pm < 0) {
|
||||||
s->pm = 1;
|
s->pm = 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x36: /* MADCTR */
|
case 0x36: /* MADCTR */
|
||||||
@@ -613,8 +627,9 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
|
|||||||
|
|
||||||
case 0xb0: /* CLKINT / DISCTL */
|
case 0xb0: /* CLKINT / DISCTL */
|
||||||
case 0xb1: /* CLKEXT */
|
case 0xb1: /* CLKEXT */
|
||||||
if (s->pm < 0)
|
if (s->pm < 0) {
|
||||||
s->pm = 2;
|
s->pm = 2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xb4: /* FRMSEL */
|
case 0xb4: /* FRMSEL */
|
||||||
@@ -635,8 +650,9 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xc2: /* IFMOD */
|
case 0xc2: /* IFMOD */
|
||||||
if (s->pm < 0)
|
if (s->pm < 0) {
|
||||||
s->pm = 2;
|
s->pm = 2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xc6: /* PWRCTL */
|
case 0xc6: /* PWRCTL */
|
||||||
@@ -834,118 +850,119 @@ static void n800_setup_nolo_tags(void *sram_base)
|
|||||||
|
|
||||||
strcpy((void *) (p + 8), "F5");
|
strcpy((void *) (p + 8), "F5");
|
||||||
|
|
||||||
stl_raw(p + 10, 0x04f70000);
|
stl_p(p + 10, 0x04f70000);
|
||||||
strcpy((void *) (p + 9), "RX-34");
|
strcpy((void *) (p + 9), "RX-34");
|
||||||
|
|
||||||
/* RAM size in MB? */
|
/* RAM size in MB? */
|
||||||
stl_raw(p + 12, 0x80);
|
stl_p(p + 12, 0x80);
|
||||||
|
|
||||||
/* Pointer to the list of tags */
|
/* Pointer to the list of tags */
|
||||||
stl_raw(p + 13, OMAP2_SRAM_BASE + 0x9000);
|
stl_p(p + 13, OMAP2_SRAM_BASE + 0x9000);
|
||||||
|
|
||||||
/* The NOLO tags start here */
|
/* The NOLO tags start here */
|
||||||
p = sram_base + 0x9000;
|
p = sram_base + 0x9000;
|
||||||
#define ADD_TAG(tag, len) \
|
#define ADD_TAG(tag, len) \
|
||||||
stw_raw((uint16_t *) p + 0, tag); \
|
stw_p((uint16_t *) p + 0, tag); \
|
||||||
stw_raw((uint16_t *) p + 1, len); p ++; \
|
stw_p((uint16_t *) p + 1, len); p++; \
|
||||||
stl_raw(p ++, OMAP2_SRAM_BASE | (((void *) v - sram_base) & 0xffff));
|
stl_p(p++, OMAP2_SRAM_BASE | (((void *) v - sram_base) & 0xffff));
|
||||||
|
|
||||||
/* OMAP STI console? Pin out settings? */
|
/* OMAP STI console? Pin out settings? */
|
||||||
ADD_TAG(0x6e01, 414);
|
ADD_TAG(0x6e01, 414);
|
||||||
for (i = 0; i < ARRAY_SIZE(n800_pinout); i ++)
|
for (i = 0; i < ARRAY_SIZE(n800_pinout); i++) {
|
||||||
stl_raw(v ++, n800_pinout[i]);
|
stl_p(v++, n800_pinout[i]);
|
||||||
|
}
|
||||||
|
|
||||||
/* Kernel memsize? */
|
/* Kernel memsize? */
|
||||||
ADD_TAG(0x6e05, 1);
|
ADD_TAG(0x6e05, 1);
|
||||||
stl_raw(v ++, 2);
|
stl_p(v++, 2);
|
||||||
|
|
||||||
/* NOLO serial console */
|
/* NOLO serial console */
|
||||||
ADD_TAG(0x6e02, 4);
|
ADD_TAG(0x6e02, 4);
|
||||||
stl_raw(v ++, XLDR_LL_UART); /* UART number (1 - 3) */
|
stl_p(v++, XLDR_LL_UART); /* UART number (1 - 3) */
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* CBUS settings (Retu/AVilma) */
|
/* CBUS settings (Retu/AVilma) */
|
||||||
ADD_TAG(0x6e03, 6);
|
ADD_TAG(0x6e03, 6);
|
||||||
stw_raw((uint16_t *) v + 0, 65); /* CBUS GPIO0 */
|
stw_p((uint16_t *) v + 0, 65); /* CBUS GPIO0 */
|
||||||
stw_raw((uint16_t *) v + 1, 66); /* CBUS GPIO1 */
|
stw_p((uint16_t *) v + 1, 66); /* CBUS GPIO1 */
|
||||||
stw_raw((uint16_t *) v + 2, 64); /* CBUS GPIO2 */
|
stw_p((uint16_t *) v + 2, 64); /* CBUS GPIO2 */
|
||||||
v += 2;
|
v += 2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Nokia ASIC BB5 (Retu/Tahvo) */
|
/* Nokia ASIC BB5 (Retu/Tahvo) */
|
||||||
ADD_TAG(0x6e0a, 4);
|
ADD_TAG(0x6e0a, 4);
|
||||||
stw_raw((uint16_t *) v + 0, 111); /* "Retu" interrupt GPIO */
|
stw_p((uint16_t *) v + 0, 111); /* "Retu" interrupt GPIO */
|
||||||
stw_raw((uint16_t *) v + 1, 108); /* "Tahvo" interrupt GPIO */
|
stw_p((uint16_t *) v + 1, 108); /* "Tahvo" interrupt GPIO */
|
||||||
v ++;
|
v++;
|
||||||
|
|
||||||
/* LCD console? */
|
/* LCD console? */
|
||||||
ADD_TAG(0x6e04, 4);
|
ADD_TAG(0x6e04, 4);
|
||||||
stw_raw((uint16_t *) v + 0, 30); /* ??? */
|
stw_p((uint16_t *) v + 0, 30); /* ??? */
|
||||||
stw_raw((uint16_t *) v + 1, 24); /* ??? */
|
stw_p((uint16_t *) v + 1, 24); /* ??? */
|
||||||
v ++;
|
v++;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* LCD settings */
|
/* LCD settings */
|
||||||
ADD_TAG(0x6e06, 2);
|
ADD_TAG(0x6e06, 2);
|
||||||
stw_raw((uint16_t *) (v ++), 15); /* ??? */
|
stw_p((uint16_t *) (v++), 15); /* ??? */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* I^2C (Menelaus) */
|
/* I^2C (Menelaus) */
|
||||||
ADD_TAG(0x6e07, 4);
|
ADD_TAG(0x6e07, 4);
|
||||||
stl_raw(v ++, 0x00720000); /* ??? */
|
stl_p(v++, 0x00720000); /* ??? */
|
||||||
|
|
||||||
/* Unknown */
|
/* Unknown */
|
||||||
ADD_TAG(0x6e0b, 6);
|
ADD_TAG(0x6e0b, 6);
|
||||||
stw_raw((uint16_t *) v + 0, 94); /* ??? */
|
stw_p((uint16_t *) v + 0, 94); /* ??? */
|
||||||
stw_raw((uint16_t *) v + 1, 23); /* ??? */
|
stw_p((uint16_t *) v + 1, 23); /* ??? */
|
||||||
stw_raw((uint16_t *) v + 2, 0); /* ??? */
|
stw_p((uint16_t *) v + 2, 0); /* ??? */
|
||||||
v += 2;
|
v += 2;
|
||||||
|
|
||||||
/* OMAP gpio switch info */
|
/* OMAP gpio switch info */
|
||||||
ADD_TAG(0x6e0c, 80);
|
ADD_TAG(0x6e0c, 80);
|
||||||
strcpy((void *) v, "bat_cover"); v += 3;
|
strcpy((void *) v, "bat_cover"); v += 3;
|
||||||
stw_raw((uint16_t *) v + 0, 110); /* GPIO num ??? */
|
stw_p((uint16_t *) v + 0, 110); /* GPIO num ??? */
|
||||||
stw_raw((uint16_t *) v + 1, 1); /* GPIO num ??? */
|
stw_p((uint16_t *) v + 1, 1); /* GPIO num ??? */
|
||||||
v += 2;
|
v += 2;
|
||||||
strcpy((void *) v, "cam_act"); v += 3;
|
strcpy((void *) v, "cam_act"); v += 3;
|
||||||
stw_raw((uint16_t *) v + 0, 95); /* GPIO num ??? */
|
stw_p((uint16_t *) v + 0, 95); /* GPIO num ??? */
|
||||||
stw_raw((uint16_t *) v + 1, 32); /* GPIO num ??? */
|
stw_p((uint16_t *) v + 1, 32); /* GPIO num ??? */
|
||||||
v += 2;
|
v += 2;
|
||||||
strcpy((void *) v, "cam_turn"); v += 3;
|
strcpy((void *) v, "cam_turn"); v += 3;
|
||||||
stw_raw((uint16_t *) v + 0, 12); /* GPIO num ??? */
|
stw_p((uint16_t *) v + 0, 12); /* GPIO num ??? */
|
||||||
stw_raw((uint16_t *) v + 1, 33); /* GPIO num ??? */
|
stw_p((uint16_t *) v + 1, 33); /* GPIO num ??? */
|
||||||
v += 2;
|
v += 2;
|
||||||
strcpy((void *) v, "headphone"); v += 3;
|
strcpy((void *) v, "headphone"); v += 3;
|
||||||
stw_raw((uint16_t *) v + 0, 107); /* GPIO num ??? */
|
stw_p((uint16_t *) v + 0, 107); /* GPIO num ??? */
|
||||||
stw_raw((uint16_t *) v + 1, 17); /* GPIO num ??? */
|
stw_p((uint16_t *) v + 1, 17); /* GPIO num ??? */
|
||||||
v += 2;
|
v += 2;
|
||||||
|
|
||||||
/* Bluetooth */
|
/* Bluetooth */
|
||||||
ADD_TAG(0x6e0e, 12);
|
ADD_TAG(0x6e0e, 12);
|
||||||
stl_raw(v ++, 0x5c623d01); /* ??? */
|
stl_p(v++, 0x5c623d01); /* ??? */
|
||||||
stl_raw(v ++, 0x00000201); /* ??? */
|
stl_p(v++, 0x00000201); /* ??? */
|
||||||
stl_raw(v ++, 0x00000000); /* ??? */
|
stl_p(v++, 0x00000000); /* ??? */
|
||||||
|
|
||||||
/* CX3110x WLAN settings */
|
/* CX3110x WLAN settings */
|
||||||
ADD_TAG(0x6e0f, 8);
|
ADD_TAG(0x6e0f, 8);
|
||||||
stl_raw(v ++, 0x00610025); /* ??? */
|
stl_p(v++, 0x00610025); /* ??? */
|
||||||
stl_raw(v ++, 0xffff0057); /* ??? */
|
stl_p(v++, 0xffff0057); /* ??? */
|
||||||
|
|
||||||
/* MMC host settings */
|
/* MMC host settings */
|
||||||
ADD_TAG(0x6e10, 12);
|
ADD_TAG(0x6e10, 12);
|
||||||
stl_raw(v ++, 0xffff000f); /* ??? */
|
stl_p(v++, 0xffff000f); /* ??? */
|
||||||
stl_raw(v ++, 0xffffffff); /* ??? */
|
stl_p(v++, 0xffffffff); /* ??? */
|
||||||
stl_raw(v ++, 0x00000060); /* ??? */
|
stl_p(v++, 0x00000060); /* ??? */
|
||||||
|
|
||||||
/* OneNAND chip select */
|
/* OneNAND chip select */
|
||||||
ADD_TAG(0x6e11, 10);
|
ADD_TAG(0x6e11, 10);
|
||||||
stl_raw(v ++, 0x00000401); /* ??? */
|
stl_p(v++, 0x00000401); /* ??? */
|
||||||
stl_raw(v ++, 0x0002003a); /* ??? */
|
stl_p(v++, 0x0002003a); /* ??? */
|
||||||
stl_raw(v ++, 0x00000002); /* ??? */
|
stl_p(v++, 0x00000002); /* ??? */
|
||||||
|
|
||||||
/* TEA5761 sensor settings */
|
/* TEA5761 sensor settings */
|
||||||
ADD_TAG(0x6e12, 2);
|
ADD_TAG(0x6e12, 2);
|
||||||
stl_raw(v ++, 93); /* GPIO num ??? */
|
stl_p(v++, 93); /* GPIO num ??? */
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* Unknown tag */
|
/* Unknown tag */
|
||||||
@@ -956,8 +973,8 @@ static void n800_setup_nolo_tags(void *sram_base)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* End of the list */
|
/* End of the list */
|
||||||
stl_raw(p ++, 0x00000000);
|
stl_p(p++, 0x00000000);
|
||||||
stl_raw(p ++, 0x00000000);
|
stl_p(p++, 0x00000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This task is normally performed by the bootloader. If we're loading
|
/* This task is normally performed by the bootloader. If we're loading
|
||||||
@@ -1032,8 +1049,9 @@ static void n8x0_boot_init(void *opaque)
|
|||||||
s->mpu->cpu->env.GE = 0x5;
|
s->mpu->cpu->env.GE = 0x5;
|
||||||
|
|
||||||
/* If the machine has a slided keyboard, open it */
|
/* If the machine has a slided keyboard, open it */
|
||||||
if (s->kbd)
|
if (s->kbd) {
|
||||||
qemu_irq_raise(qdev_get_gpio_in(s->mpu->gpio, N810_SLIDE_GPIO));
|
qemu_irq_raise(qdev_get_gpio_in(s->mpu->gpio, N810_SLIDE_GPIO));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OMAP_TAG_NOKIA_BT 0x4e01
|
#define OMAP_TAG_NOKIA_BT 0x4e01
|
||||||
@@ -1119,112 +1137,112 @@ static int n8x0_atag_setup(void *p, int model)
|
|||||||
|
|
||||||
w = p;
|
w = p;
|
||||||
|
|
||||||
stw_raw(w ++, OMAP_TAG_UART); /* u16 tag */
|
stw_p(w++, OMAP_TAG_UART); /* u16 tag */
|
||||||
stw_raw(w ++, 4); /* u16 len */
|
stw_p(w++, 4); /* u16 len */
|
||||||
stw_raw(w ++, (1 << 2) | (1 << 1) | (1 << 0)); /* uint enabled_uarts */
|
stw_p(w++, (1 << 2) | (1 << 1) | (1 << 0)); /* uint enabled_uarts */
|
||||||
w ++;
|
w++;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
stw_raw(w ++, OMAP_TAG_SERIAL_CONSOLE); /* u16 tag */
|
stw_p(w++, OMAP_TAG_SERIAL_CONSOLE); /* u16 tag */
|
||||||
stw_raw(w ++, 4); /* u16 len */
|
stw_p(w++, 4); /* u16 len */
|
||||||
stw_raw(w ++, XLDR_LL_UART + 1); /* u8 console_uart */
|
stw_p(w++, XLDR_LL_UART + 1); /* u8 console_uart */
|
||||||
stw_raw(w ++, 115200); /* u32 console_speed */
|
stw_p(w++, 115200); /* u32 console_speed */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
stw_raw(w ++, OMAP_TAG_LCD); /* u16 tag */
|
stw_p(w++, OMAP_TAG_LCD); /* u16 tag */
|
||||||
stw_raw(w ++, 36); /* u16 len */
|
stw_p(w++, 36); /* u16 len */
|
||||||
strcpy((void *) w, "QEMU LCD panel"); /* char panel_name[16] */
|
strcpy((void *) w, "QEMU LCD panel"); /* char panel_name[16] */
|
||||||
w += 8;
|
w += 8;
|
||||||
strcpy((void *) w, "blizzard"); /* char ctrl_name[16] */
|
strcpy((void *) w, "blizzard"); /* char ctrl_name[16] */
|
||||||
w += 8;
|
w += 8;
|
||||||
stw_raw(w ++, N810_BLIZZARD_RESET_GPIO); /* TODO: n800 s16 nreset_gpio */
|
stw_p(w++, N810_BLIZZARD_RESET_GPIO); /* TODO: n800 s16 nreset_gpio */
|
||||||
stw_raw(w ++, 24); /* u8 data_lines */
|
stw_p(w++, 24); /* u8 data_lines */
|
||||||
|
|
||||||
stw_raw(w ++, OMAP_TAG_CBUS); /* u16 tag */
|
stw_p(w++, OMAP_TAG_CBUS); /* u16 tag */
|
||||||
stw_raw(w ++, 8); /* u16 len */
|
stw_p(w++, 8); /* u16 len */
|
||||||
stw_raw(w ++, N8X0_CBUS_CLK_GPIO); /* s16 clk_gpio */
|
stw_p(w++, N8X0_CBUS_CLK_GPIO); /* s16 clk_gpio */
|
||||||
stw_raw(w ++, N8X0_CBUS_DAT_GPIO); /* s16 dat_gpio */
|
stw_p(w++, N8X0_CBUS_DAT_GPIO); /* s16 dat_gpio */
|
||||||
stw_raw(w ++, N8X0_CBUS_SEL_GPIO); /* s16 sel_gpio */
|
stw_p(w++, N8X0_CBUS_SEL_GPIO); /* s16 sel_gpio */
|
||||||
w ++;
|
w++;
|
||||||
|
|
||||||
stw_raw(w ++, OMAP_TAG_EM_ASIC_BB5); /* u16 tag */
|
stw_p(w++, OMAP_TAG_EM_ASIC_BB5); /* u16 tag */
|
||||||
stw_raw(w ++, 4); /* u16 len */
|
stw_p(w++, 4); /* u16 len */
|
||||||
stw_raw(w ++, N8X0_RETU_GPIO); /* s16 retu_irq_gpio */
|
stw_p(w++, N8X0_RETU_GPIO); /* s16 retu_irq_gpio */
|
||||||
stw_raw(w ++, N8X0_TAHVO_GPIO); /* s16 tahvo_irq_gpio */
|
stw_p(w++, N8X0_TAHVO_GPIO); /* s16 tahvo_irq_gpio */
|
||||||
|
|
||||||
gpiosw = (model == 810) ? n810_gpiosw_info : n800_gpiosw_info;
|
gpiosw = (model == 810) ? n810_gpiosw_info : n800_gpiosw_info;
|
||||||
for (; gpiosw->name; gpiosw ++) {
|
for (; gpiosw->name; gpiosw++) {
|
||||||
stw_raw(w ++, OMAP_TAG_GPIO_SWITCH); /* u16 tag */
|
stw_p(w++, OMAP_TAG_GPIO_SWITCH); /* u16 tag */
|
||||||
stw_raw(w ++, 20); /* u16 len */
|
stw_p(w++, 20); /* u16 len */
|
||||||
strcpy((void *) w, gpiosw->name); /* char name[12] */
|
strcpy((void *) w, gpiosw->name); /* char name[12] */
|
||||||
w += 6;
|
w += 6;
|
||||||
stw_raw(w ++, gpiosw->line); /* u16 gpio */
|
stw_p(w++, gpiosw->line); /* u16 gpio */
|
||||||
stw_raw(w ++, gpiosw->type);
|
stw_p(w++, gpiosw->type);
|
||||||
stw_raw(w ++, 0);
|
stw_p(w++, 0);
|
||||||
stw_raw(w ++, 0);
|
stw_p(w++, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
stw_raw(w ++, OMAP_TAG_NOKIA_BT); /* u16 tag */
|
stw_p(w++, OMAP_TAG_NOKIA_BT); /* u16 tag */
|
||||||
stw_raw(w ++, 12); /* u16 len */
|
stw_p(w++, 12); /* u16 len */
|
||||||
b = (void *) w;
|
b = (void *) w;
|
||||||
stb_raw(b ++, 0x01); /* u8 chip_type (CSR) */
|
stb_p(b++, 0x01); /* u8 chip_type (CSR) */
|
||||||
stb_raw(b ++, N8X0_BT_WKUP_GPIO); /* u8 bt_wakeup_gpio */
|
stb_p(b++, N8X0_BT_WKUP_GPIO); /* u8 bt_wakeup_gpio */
|
||||||
stb_raw(b ++, N8X0_BT_HOST_WKUP_GPIO); /* u8 host_wakeup_gpio */
|
stb_p(b++, N8X0_BT_HOST_WKUP_GPIO); /* u8 host_wakeup_gpio */
|
||||||
stb_raw(b ++, N8X0_BT_RESET_GPIO); /* u8 reset_gpio */
|
stb_p(b++, N8X0_BT_RESET_GPIO); /* u8 reset_gpio */
|
||||||
stb_raw(b ++, BT_UART + 1); /* u8 bt_uart */
|
stb_p(b++, BT_UART + 1); /* u8 bt_uart */
|
||||||
memcpy(b, &n8x0_bd_addr, 6); /* u8 bd_addr[6] */
|
memcpy(b, &n8x0_bd_addr, 6); /* u8 bd_addr[6] */
|
||||||
b += 6;
|
b += 6;
|
||||||
stb_raw(b ++, 0x02); /* u8 bt_sysclk (38.4) */
|
stb_p(b++, 0x02); /* u8 bt_sysclk (38.4) */
|
||||||
w = (void *) b;
|
w = (void *) b;
|
||||||
|
|
||||||
stw_raw(w ++, OMAP_TAG_WLAN_CX3110X); /* u16 tag */
|
stw_p(w++, OMAP_TAG_WLAN_CX3110X); /* u16 tag */
|
||||||
stw_raw(w ++, 8); /* u16 len */
|
stw_p(w++, 8); /* u16 len */
|
||||||
stw_raw(w ++, 0x25); /* u8 chip_type */
|
stw_p(w++, 0x25); /* u8 chip_type */
|
||||||
stw_raw(w ++, N8X0_WLAN_PWR_GPIO); /* s16 power_gpio */
|
stw_p(w++, N8X0_WLAN_PWR_GPIO); /* s16 power_gpio */
|
||||||
stw_raw(w ++, N8X0_WLAN_IRQ_GPIO); /* s16 irq_gpio */
|
stw_p(w++, N8X0_WLAN_IRQ_GPIO); /* s16 irq_gpio */
|
||||||
stw_raw(w ++, -1); /* s16 spi_cs_gpio */
|
stw_p(w++, -1); /* s16 spi_cs_gpio */
|
||||||
|
|
||||||
stw_raw(w ++, OMAP_TAG_MMC); /* u16 tag */
|
stw_p(w++, OMAP_TAG_MMC); /* u16 tag */
|
||||||
stw_raw(w ++, 16); /* u16 len */
|
stw_p(w++, 16); /* u16 len */
|
||||||
if (model == 810) {
|
if (model == 810) {
|
||||||
stw_raw(w ++, 0x23f); /* unsigned flags */
|
stw_p(w++, 0x23f); /* unsigned flags */
|
||||||
stw_raw(w ++, -1); /* s16 power_pin */
|
stw_p(w++, -1); /* s16 power_pin */
|
||||||
stw_raw(w ++, -1); /* s16 switch_pin */
|
stw_p(w++, -1); /* s16 switch_pin */
|
||||||
stw_raw(w ++, -1); /* s16 wp_pin */
|
stw_p(w++, -1); /* s16 wp_pin */
|
||||||
stw_raw(w ++, 0x240); /* unsigned flags */
|
stw_p(w++, 0x240); /* unsigned flags */
|
||||||
stw_raw(w ++, 0xc000); /* s16 power_pin */
|
stw_p(w++, 0xc000); /* s16 power_pin */
|
||||||
stw_raw(w ++, 0x0248); /* s16 switch_pin */
|
stw_p(w++, 0x0248); /* s16 switch_pin */
|
||||||
stw_raw(w ++, 0xc000); /* s16 wp_pin */
|
stw_p(w++, 0xc000); /* s16 wp_pin */
|
||||||
} else {
|
} else {
|
||||||
stw_raw(w ++, 0xf); /* unsigned flags */
|
stw_p(w++, 0xf); /* unsigned flags */
|
||||||
stw_raw(w ++, -1); /* s16 power_pin */
|
stw_p(w++, -1); /* s16 power_pin */
|
||||||
stw_raw(w ++, -1); /* s16 switch_pin */
|
stw_p(w++, -1); /* s16 switch_pin */
|
||||||
stw_raw(w ++, -1); /* s16 wp_pin */
|
stw_p(w++, -1); /* s16 wp_pin */
|
||||||
stw_raw(w ++, 0); /* unsigned flags */
|
stw_p(w++, 0); /* unsigned flags */
|
||||||
stw_raw(w ++, 0); /* s16 power_pin */
|
stw_p(w++, 0); /* s16 power_pin */
|
||||||
stw_raw(w ++, 0); /* s16 switch_pin */
|
stw_p(w++, 0); /* s16 switch_pin */
|
||||||
stw_raw(w ++, 0); /* s16 wp_pin */
|
stw_p(w++, 0); /* s16 wp_pin */
|
||||||
}
|
}
|
||||||
|
|
||||||
stw_raw(w ++, OMAP_TAG_TEA5761); /* u16 tag */
|
stw_p(w++, OMAP_TAG_TEA5761); /* u16 tag */
|
||||||
stw_raw(w ++, 4); /* u16 len */
|
stw_p(w++, 4); /* u16 len */
|
||||||
stw_raw(w ++, N8X0_TEA5761_CS_GPIO); /* u16 enable_gpio */
|
stw_p(w++, N8X0_TEA5761_CS_GPIO); /* u16 enable_gpio */
|
||||||
w ++;
|
w++;
|
||||||
|
|
||||||
partition = (model == 810) ? n810_part_info : n800_part_info;
|
partition = (model == 810) ? n810_part_info : n800_part_info;
|
||||||
for (; partition->name; partition ++) {
|
for (; partition->name; partition++) {
|
||||||
stw_raw(w ++, OMAP_TAG_PARTITION); /* u16 tag */
|
stw_p(w++, OMAP_TAG_PARTITION); /* u16 tag */
|
||||||
stw_raw(w ++, 28); /* u16 len */
|
stw_p(w++, 28); /* u16 len */
|
||||||
strcpy((void *) w, partition->name); /* char name[16] */
|
strcpy((void *) w, partition->name); /* char name[16] */
|
||||||
l = (void *) (w + 8);
|
l = (void *) (w + 8);
|
||||||
stl_raw(l ++, partition->size); /* unsigned int size */
|
stl_p(l++, partition->size); /* unsigned int size */
|
||||||
stl_raw(l ++, partition->offset); /* unsigned int offset */
|
stl_p(l++, partition->offset); /* unsigned int offset */
|
||||||
stl_raw(l ++, partition->mask); /* unsigned int mask_flags */
|
stl_p(l++, partition->mask); /* unsigned int mask_flags */
|
||||||
w = (void *) l;
|
w = (void *) l;
|
||||||
}
|
}
|
||||||
|
|
||||||
stw_raw(w ++, OMAP_TAG_BOOT_REASON); /* u16 tag */
|
stw_p(w++, OMAP_TAG_BOOT_REASON); /* u16 tag */
|
||||||
stw_raw(w ++, 12); /* u16 len */
|
stw_p(w++, 12); /* u16 len */
|
||||||
#if 0
|
#if 0
|
||||||
strcpy((void *) w, "por"); /* char reason_str[12] */
|
strcpy((void *) w, "por"); /* char reason_str[12] */
|
||||||
strcpy((void *) w, "charger"); /* char reason_str[12] */
|
strcpy((void *) w, "charger"); /* char reason_str[12] */
|
||||||
@@ -1242,15 +1260,15 @@ static int n8x0_atag_setup(void *p, int model)
|
|||||||
w += 6;
|
w += 6;
|
||||||
|
|
||||||
tag = (model == 810) ? "RX-44" : "RX-34";
|
tag = (model == 810) ? "RX-44" : "RX-34";
|
||||||
stw_raw(w ++, OMAP_TAG_VERSION_STR); /* u16 tag */
|
stw_p(w++, OMAP_TAG_VERSION_STR); /* u16 tag */
|
||||||
stw_raw(w ++, 24); /* u16 len */
|
stw_p(w++, 24); /* u16 len */
|
||||||
strcpy((void *) w, "product"); /* char component[12] */
|
strcpy((void *) w, "product"); /* char component[12] */
|
||||||
w += 6;
|
w += 6;
|
||||||
strcpy((void *) w, tag); /* char version[12] */
|
strcpy((void *) w, tag); /* char version[12] */
|
||||||
w += 6;
|
w += 6;
|
||||||
|
|
||||||
stw_raw(w ++, OMAP_TAG_VERSION_STR); /* u16 tag */
|
stw_p(w++, OMAP_TAG_VERSION_STR); /* u16 tag */
|
||||||
stw_raw(w ++, 24); /* u16 len */
|
stw_p(w++, 24); /* u16 len */
|
||||||
strcpy((void *) w, "hw-build"); /* char component[12] */
|
strcpy((void *) w, "hw-build"); /* char component[12] */
|
||||||
w += 6;
|
w += 6;
|
||||||
strcpy((void *) w, "QEMU ");
|
strcpy((void *) w, "QEMU ");
|
||||||
@@ -1258,8 +1276,8 @@ static int n8x0_atag_setup(void *p, int model)
|
|||||||
w += 6;
|
w += 6;
|
||||||
|
|
||||||
tag = (model == 810) ? "1.1.10-qemu" : "1.1.6-qemu";
|
tag = (model == 810) ? "1.1.10-qemu" : "1.1.6-qemu";
|
||||||
stw_raw(w ++, OMAP_TAG_VERSION_STR); /* u16 tag */
|
stw_p(w++, OMAP_TAG_VERSION_STR); /* u16 tag */
|
||||||
stw_raw(w ++, 24); /* u16 len */
|
stw_p(w++, 24); /* u16 len */
|
||||||
strcpy((void *) w, "nolo"); /* char component[12] */
|
strcpy((void *) w, "nolo"); /* char component[12] */
|
||||||
w += 6;
|
w += 6;
|
||||||
strcpy((void *) w, tag); /* char version[12] */
|
strcpy((void *) w, tag); /* char version[12] */
|
||||||
@@ -1315,9 +1333,9 @@ static void n8x0_init(MachineState *machine,
|
|||||||
n8x0_gpio_setup(s);
|
n8x0_gpio_setup(s);
|
||||||
n8x0_nand_setup(s);
|
n8x0_nand_setup(s);
|
||||||
n8x0_i2c_setup(s);
|
n8x0_i2c_setup(s);
|
||||||
if (model == 800)
|
if (model == 800) {
|
||||||
n800_tsc_kbd_setup(s);
|
n800_tsc_kbd_setup(s);
|
||||||
else if (model == 810) {
|
} else if (model == 810) {
|
||||||
n810_tsc_setup(s);
|
n810_tsc_setup(s);
|
||||||
n810_kbd_setup(s);
|
n810_kbd_setup(s);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "net/net.h"
|
#include "net/net.h"
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "hw/boards.h"
|
#include "hw/boards.h"
|
||||||
|
#include "hw/loader.h"
|
||||||
#include "exec/address-spaces.h"
|
#include "exec/address-spaces.h"
|
||||||
#include "sysemu/blockdev.h"
|
#include "sysemu/blockdev.h"
|
||||||
#include "hw/block/flash.h"
|
#include "hw/block/flash.h"
|
||||||
@@ -528,6 +529,18 @@ static void vexpress_common_init(VEDBoardInfo *daughterboard,
|
|||||||
daughterboard->init(daughterboard, machine->ram_size, machine->cpu_model,
|
daughterboard->init(daughterboard, machine->ram_size, machine->cpu_model,
|
||||||
pic);
|
pic);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a bios file was provided, attempt to map it into memory
|
||||||
|
*/
|
||||||
|
if (bios_name) {
|
||||||
|
const char *fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
|
||||||
|
if (!fn || load_image_targphys(fn, map[VE_NORFLASH0],
|
||||||
|
VEXPRESS_FLASH_SIZE) < 0) {
|
||||||
|
error_report("Could not load ROM image '%s'", bios_name);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Motherboard peripherals: the wiring is the same but the
|
/* Motherboard peripherals: the wiring is the same but the
|
||||||
* addresses vary between the legacy and A-Series memory maps.
|
* addresses vary between the legacy and A-Series memory maps.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1163,8 +1163,7 @@ static const VMStateDescription vmstate_ac97_bm_regs = {
|
|||||||
.name = "ac97_bm_regs",
|
.name = "ac97_bm_regs",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.minimum_version_id_old = 1,
|
.fields = (VMStateField[]) {
|
||||||
.fields = (VMStateField []) {
|
|
||||||
VMSTATE_UINT32 (bdbar, AC97BusMasterRegs),
|
VMSTATE_UINT32 (bdbar, AC97BusMasterRegs),
|
||||||
VMSTATE_UINT8 (civ, AC97BusMasterRegs),
|
VMSTATE_UINT8 (civ, AC97BusMasterRegs),
|
||||||
VMSTATE_UINT8 (lvi, AC97BusMasterRegs),
|
VMSTATE_UINT8 (lvi, AC97BusMasterRegs),
|
||||||
@@ -1211,9 +1210,8 @@ static const VMStateDescription vmstate_ac97 = {
|
|||||||
.name = "ac97",
|
.name = "ac97",
|
||||||
.version_id = 3,
|
.version_id = 3,
|
||||||
.minimum_version_id = 2,
|
.minimum_version_id = 2,
|
||||||
.minimum_version_id_old = 2,
|
|
||||||
.post_load = ac97_post_load,
|
.post_load = ac97_post_load,
|
||||||
.fields = (VMStateField []) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_PCI_DEVICE (dev, AC97LinkState),
|
VMSTATE_PCI_DEVICE (dev, AC97LinkState),
|
||||||
VMSTATE_UINT32 (glob_cnt, AC97LinkState),
|
VMSTATE_UINT32 (glob_cnt, AC97LinkState),
|
||||||
VMSTATE_UINT32 (glob_sta, AC97LinkState),
|
VMSTATE_UINT32 (glob_sta, AC97LinkState),
|
||||||
|
|||||||
@@ -275,9 +275,7 @@ static void Adlib_fini (AdlibState *s)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (s->mixbuf) {
|
g_free(s->mixbuf);
|
||||||
g_free (s->mixbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
s->active = 0;
|
s->active = 0;
|
||||||
s->enabled = 0;
|
s->enabled = 0;
|
||||||
|
|||||||
@@ -137,8 +137,7 @@ static const VMStateDescription vmstate_cs4231 = {
|
|||||||
.name ="cs4231",
|
.name ="cs4231",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.minimum_version_id_old = 1,
|
.fields = (VMStateField[]) {
|
||||||
.fields = (VMStateField []) {
|
|
||||||
VMSTATE_UINT32_ARRAY(regs, CSState, CS_REGS),
|
VMSTATE_UINT32_ARRAY(regs, CSState, CS_REGS),
|
||||||
VMSTATE_UINT8_ARRAY(dregs, CSState, CS_DREGS),
|
VMSTATE_UINT8_ARRAY(dregs, CSState, CS_DREGS),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
|
|||||||
@@ -621,10 +621,9 @@ static const VMStateDescription vmstate_cs4231a = {
|
|||||||
.name = "cs4231a",
|
.name = "cs4231a",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.minimum_version_id_old = 1,
|
|
||||||
.pre_load = cs4231a_pre_load,
|
.pre_load = cs4231a_pre_load,
|
||||||
.post_load = cs4231a_post_load,
|
.post_load = cs4231a_post_load,
|
||||||
.fields = (VMStateField []) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_UINT32_ARRAY (regs, CSState, CS_REGS),
|
VMSTATE_UINT32_ARRAY (regs, CSState, CS_REGS),
|
||||||
VMSTATE_BUFFER (dregs, CSState),
|
VMSTATE_BUFFER (dregs, CSState),
|
||||||
VMSTATE_INT32 (dma_running, CSState),
|
VMSTATE_INT32 (dma_running, CSState),
|
||||||
|
|||||||
@@ -953,8 +953,7 @@ static const VMStateDescription vmstate_es1370_channel = {
|
|||||||
.name = "es1370_channel",
|
.name = "es1370_channel",
|
||||||
.version_id = 2,
|
.version_id = 2,
|
||||||
.minimum_version_id = 2,
|
.minimum_version_id = 2,
|
||||||
.minimum_version_id_old = 2,
|
.fields = (VMStateField[]) {
|
||||||
.fields = (VMStateField []) {
|
|
||||||
VMSTATE_UINT32 (shift, struct chan),
|
VMSTATE_UINT32 (shift, struct chan),
|
||||||
VMSTATE_UINT32 (leftover, struct chan),
|
VMSTATE_UINT32 (leftover, struct chan),
|
||||||
VMSTATE_UINT32 (scount, struct chan),
|
VMSTATE_UINT32 (scount, struct chan),
|
||||||
@@ -997,9 +996,8 @@ static const VMStateDescription vmstate_es1370 = {
|
|||||||
.name = "es1370",
|
.name = "es1370",
|
||||||
.version_id = 2,
|
.version_id = 2,
|
||||||
.minimum_version_id = 2,
|
.minimum_version_id = 2,
|
||||||
.minimum_version_id_old = 2,
|
|
||||||
.post_load = es1370_post_load,
|
.post_load = es1370_post_load,
|
||||||
.fields = (VMStateField []) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_PCI_DEVICE (dev, ES1370State),
|
VMSTATE_PCI_DEVICE (dev, ES1370State),
|
||||||
VMSTATE_STRUCT_ARRAY (chan, ES1370State, NB_CHANNELS, 2,
|
VMSTATE_STRUCT_ARRAY (chan, ES1370State, NB_CHANNELS, 2,
|
||||||
vmstate_es1370_channel, struct chan),
|
vmstate_es1370_channel, struct chan),
|
||||||
|
|||||||
@@ -222,8 +222,7 @@ static const VMStateDescription vmstate_gus = {
|
|||||||
.name = "gus",
|
.name = "gus",
|
||||||
.version_id = 2,
|
.version_id = 2,
|
||||||
.minimum_version_id = 2,
|
.minimum_version_id = 2,
|
||||||
.minimum_version_id_old = 2,
|
.fields = (VMStateField[]) {
|
||||||
.fields = (VMStateField []) {
|
|
||||||
VMSTATE_INT32 (pos, GUSState),
|
VMSTATE_INT32 (pos, GUSState),
|
||||||
VMSTATE_INT32 (left, GUSState),
|
VMSTATE_INT32 (left, GUSState),
|
||||||
VMSTATE_INT32 (shift, GUSState),
|
VMSTATE_INT32 (shift, GUSState),
|
||||||
|
|||||||
@@ -583,7 +583,7 @@ static void hda_audio_reset(DeviceState *dev)
|
|||||||
static const VMStateDescription vmstate_hda_audio_stream = {
|
static const VMStateDescription vmstate_hda_audio_stream = {
|
||||||
.name = "hda-audio-stream",
|
.name = "hda-audio-stream",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.fields = (VMStateField []) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_UINT32(stream, HDAAudioStream),
|
VMSTATE_UINT32(stream, HDAAudioStream),
|
||||||
VMSTATE_UINT32(channel, HDAAudioStream),
|
VMSTATE_UINT32(channel, HDAAudioStream),
|
||||||
VMSTATE_UINT32(format, HDAAudioStream),
|
VMSTATE_UINT32(format, HDAAudioStream),
|
||||||
@@ -601,7 +601,7 @@ static const VMStateDescription vmstate_hda_audio = {
|
|||||||
.name = "hda-audio",
|
.name = "hda-audio",
|
||||||
.version_id = 2,
|
.version_id = 2,
|
||||||
.post_load = hda_audio_post_load,
|
.post_load = hda_audio_post_load,
|
||||||
.fields = (VMStateField []) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0,
|
VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0,
|
||||||
vmstate_hda_audio_stream,
|
vmstate_hda_audio_stream,
|
||||||
HDAAudioStream),
|
HDAAudioStream),
|
||||||
|
|||||||
@@ -1176,7 +1176,7 @@ static int intel_hda_post_load(void *opaque, int version)
|
|||||||
static const VMStateDescription vmstate_intel_hda_stream = {
|
static const VMStateDescription vmstate_intel_hda_stream = {
|
||||||
.name = "intel-hda-stream",
|
.name = "intel-hda-stream",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.fields = (VMStateField []) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_UINT32(ctl, IntelHDAStream),
|
VMSTATE_UINT32(ctl, IntelHDAStream),
|
||||||
VMSTATE_UINT32(lpib, IntelHDAStream),
|
VMSTATE_UINT32(lpib, IntelHDAStream),
|
||||||
VMSTATE_UINT32(cbl, IntelHDAStream),
|
VMSTATE_UINT32(cbl, IntelHDAStream),
|
||||||
@@ -1192,7 +1192,7 @@ static const VMStateDescription vmstate_intel_hda = {
|
|||||||
.name = "intel-hda",
|
.name = "intel-hda",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.post_load = intel_hda_post_load,
|
.post_load = intel_hda_post_load,
|
||||||
.fields = (VMStateField []) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_PCI_DEVICE(pci, IntelHDAState),
|
VMSTATE_PCI_DEVICE(pci, IntelHDAState),
|
||||||
|
|
||||||
/* registers */
|
/* registers */
|
||||||
|
|||||||
@@ -1289,9 +1289,8 @@ static const VMStateDescription vmstate_sb16 = {
|
|||||||
.name = "sb16",
|
.name = "sb16",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.minimum_version_id_old = 1,
|
|
||||||
.post_load = sb16_post_load,
|
.post_load = sb16_post_load,
|
||||||
.fields = (VMStateField []) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_UINT32 (irq, SB16State),
|
VMSTATE_UINT32 (irq, SB16State),
|
||||||
VMSTATE_UINT32 (dma, SB16State),
|
VMSTATE_UINT32 (dma, SB16State),
|
||||||
VMSTATE_UINT32 (hdma, SB16State),
|
VMSTATE_UINT32 (hdma, SB16State),
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
obj-y += ioq.o virtio-blk.o
|
obj-y += virtio-blk.o
|
||||||
|
|||||||
@@ -1,117 +0,0 @@
|
|||||||
/*
|
|
||||||
* Linux AIO request queue
|
|
||||||
*
|
|
||||||
* Copyright 2012 IBM, Corp.
|
|
||||||
* Copyright 2012 Red Hat, Inc. and/or its affiliates
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Stefan Hajnoczi <stefanha@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
||||||
* See the COPYING file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ioq.h"
|
|
||||||
|
|
||||||
void ioq_init(IOQueue *ioq, int fd, unsigned int max_reqs)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
ioq->fd = fd;
|
|
||||||
ioq->max_reqs = max_reqs;
|
|
||||||
|
|
||||||
memset(&ioq->io_ctx, 0, sizeof ioq->io_ctx);
|
|
||||||
rc = io_setup(max_reqs, &ioq->io_ctx);
|
|
||||||
if (rc != 0) {
|
|
||||||
fprintf(stderr, "ioq io_setup failed %d\n", rc);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = event_notifier_init(&ioq->io_notifier, 0);
|
|
||||||
if (rc != 0) {
|
|
||||||
fprintf(stderr, "ioq io event notifier creation failed %d\n", rc);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
ioq->freelist = g_malloc0(sizeof ioq->freelist[0] * max_reqs);
|
|
||||||
ioq->freelist_idx = 0;
|
|
||||||
|
|
||||||
ioq->queue = g_malloc0(sizeof ioq->queue[0] * max_reqs);
|
|
||||||
ioq->queue_idx = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ioq_cleanup(IOQueue *ioq)
|
|
||||||
{
|
|
||||||
g_free(ioq->freelist);
|
|
||||||
g_free(ioq->queue);
|
|
||||||
|
|
||||||
event_notifier_cleanup(&ioq->io_notifier);
|
|
||||||
io_destroy(ioq->io_ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
EventNotifier *ioq_get_notifier(IOQueue *ioq)
|
|
||||||
{
|
|
||||||
return &ioq->io_notifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct iocb *ioq_get_iocb(IOQueue *ioq)
|
|
||||||
{
|
|
||||||
/* Underflow cannot happen since ioq is sized for max_reqs */
|
|
||||||
assert(ioq->freelist_idx != 0);
|
|
||||||
|
|
||||||
struct iocb *iocb = ioq->freelist[--ioq->freelist_idx];
|
|
||||||
ioq->queue[ioq->queue_idx++] = iocb;
|
|
||||||
return iocb;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ioq_put_iocb(IOQueue *ioq, struct iocb *iocb)
|
|
||||||
{
|
|
||||||
/* Overflow cannot happen since ioq is sized for max_reqs */
|
|
||||||
assert(ioq->freelist_idx != ioq->max_reqs);
|
|
||||||
|
|
||||||
ioq->freelist[ioq->freelist_idx++] = iocb;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct iocb *ioq_rdwr(IOQueue *ioq, bool read, struct iovec *iov,
|
|
||||||
unsigned int count, long long offset)
|
|
||||||
{
|
|
||||||
struct iocb *iocb = ioq_get_iocb(ioq);
|
|
||||||
|
|
||||||
if (read) {
|
|
||||||
io_prep_preadv(iocb, ioq->fd, iov, count, offset);
|
|
||||||
} else {
|
|
||||||
io_prep_pwritev(iocb, ioq->fd, iov, count, offset);
|
|
||||||
}
|
|
||||||
io_set_eventfd(iocb, event_notifier_get_fd(&ioq->io_notifier));
|
|
||||||
return iocb;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ioq_submit(IOQueue *ioq)
|
|
||||||
{
|
|
||||||
int rc = io_submit(ioq->io_ctx, ioq->queue_idx, ioq->queue);
|
|
||||||
ioq->queue_idx = 0; /* reset */
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ioq_run_completion(IOQueue *ioq, IOQueueCompletion *completion,
|
|
||||||
void *opaque)
|
|
||||||
{
|
|
||||||
struct io_event events[ioq->max_reqs];
|
|
||||||
int nevents, i;
|
|
||||||
|
|
||||||
do {
|
|
||||||
nevents = io_getevents(ioq->io_ctx, 0, ioq->max_reqs, events, NULL);
|
|
||||||
} while (nevents < 0 && errno == EINTR);
|
|
||||||
if (nevents < 0) {
|
|
||||||
return nevents;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < nevents; i++) {
|
|
||||||
ssize_t ret = ((uint64_t)events[i].res2 << 32) | events[i].res;
|
|
||||||
|
|
||||||
completion(events[i].obj, ret, opaque);
|
|
||||||
ioq_put_iocb(ioq, events[i].obj);
|
|
||||||
}
|
|
||||||
return nevents;
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* Linux AIO request queue
|
|
||||||
*
|
|
||||||
* Copyright 2012 IBM, Corp.
|
|
||||||
* Copyright 2012 Red Hat, Inc. and/or its affiliates
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Stefan Hajnoczi <stefanha@redhat.com>
|
|
||||||
*
|
|
||||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
||||||
* See the COPYING file in the top-level directory.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef IOQ_H
|
|
||||||
#define IOQ_H
|
|
||||||
|
|
||||||
#include <libaio.h>
|
|
||||||
#include "qemu/event_notifier.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int fd; /* file descriptor */
|
|
||||||
unsigned int max_reqs; /* max length of freelist and queue */
|
|
||||||
|
|
||||||
io_context_t io_ctx; /* Linux AIO context */
|
|
||||||
EventNotifier io_notifier; /* Linux AIO eventfd */
|
|
||||||
|
|
||||||
/* Requests can complete in any order so a free list is necessary to manage
|
|
||||||
* available iocbs.
|
|
||||||
*/
|
|
||||||
struct iocb **freelist; /* free iocbs */
|
|
||||||
unsigned int freelist_idx;
|
|
||||||
|
|
||||||
/* Multiple requests are queued up before submitting them all in one go */
|
|
||||||
struct iocb **queue; /* queued iocbs */
|
|
||||||
unsigned int queue_idx;
|
|
||||||
} IOQueue;
|
|
||||||
|
|
||||||
void ioq_init(IOQueue *ioq, int fd, unsigned int max_reqs);
|
|
||||||
void ioq_cleanup(IOQueue *ioq);
|
|
||||||
EventNotifier *ioq_get_notifier(IOQueue *ioq);
|
|
||||||
struct iocb *ioq_get_iocb(IOQueue *ioq);
|
|
||||||
void ioq_put_iocb(IOQueue *ioq, struct iocb *iocb);
|
|
||||||
struct iocb *ioq_rdwr(IOQueue *ioq, bool read, struct iovec *iov,
|
|
||||||
unsigned int count, long long offset);
|
|
||||||
int ioq_submit(IOQueue *ioq);
|
|
||||||
|
|
||||||
static inline unsigned int ioq_num_queued(IOQueue *ioq)
|
|
||||||
{
|
|
||||||
return ioq->queue_idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef void IOQueueCompletion(struct iocb *iocb, ssize_t ret, void *opaque);
|
|
||||||
int ioq_run_completion(IOQueue *ioq, IOQueueCompletion *completion,
|
|
||||||
void *opaque);
|
|
||||||
|
|
||||||
#endif /* IOQ_H */
|
|
||||||
@@ -17,7 +17,6 @@
|
|||||||
#include "qemu/thread.h"
|
#include "qemu/thread.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "hw/virtio/dataplane/vring.h"
|
#include "hw/virtio/dataplane/vring.h"
|
||||||
#include "ioq.h"
|
|
||||||
#include "block/block.h"
|
#include "block/block.h"
|
||||||
#include "hw/virtio/virtio-blk.h"
|
#include "hw/virtio/virtio-blk.h"
|
||||||
#include "virtio-blk.h"
|
#include "virtio-blk.h"
|
||||||
@@ -25,20 +24,14 @@
|
|||||||
#include "hw/virtio/virtio-bus.h"
|
#include "hw/virtio/virtio-bus.h"
|
||||||
#include "qom/object_interfaces.h"
|
#include "qom/object_interfaces.h"
|
||||||
|
|
||||||
enum {
|
|
||||||
SEG_MAX = 126, /* maximum number of I/O segments */
|
|
||||||
VRING_MAX = SEG_MAX + 2, /* maximum number of vring descriptors */
|
|
||||||
REQ_MAX = VRING_MAX, /* maximum number of requests in the vring,
|
|
||||||
* is VRING_MAX / 2 with traditional and
|
|
||||||
* VRING_MAX with indirect descriptors */
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct iocb iocb; /* Linux AIO control block */
|
VirtIOBlockDataPlane *s;
|
||||||
QEMUIOVector *inhdr; /* iovecs for virtio_blk_inhdr */
|
QEMUIOVector *inhdr; /* iovecs for virtio_blk_inhdr */
|
||||||
VirtQueueElement *elem; /* saved data from the virtqueue */
|
VirtQueueElement *elem; /* saved data from the virtqueue */
|
||||||
struct iovec *bounce_iov; /* used if guest buffers are unaligned */
|
QEMUIOVector qiov; /* original request iovecs */
|
||||||
QEMUIOVector *read_qiov; /* for read completion /w bounce buffer */
|
struct iovec bounce_iov; /* used if guest buffers are unaligned */
|
||||||
|
QEMUIOVector bounce_qiov; /* bounce buffer iovecs */
|
||||||
|
bool read; /* read or write? */
|
||||||
} VirtIOBlockRequest;
|
} VirtIOBlockRequest;
|
||||||
|
|
||||||
struct VirtIOBlockDataPlane {
|
struct VirtIOBlockDataPlane {
|
||||||
@@ -47,7 +40,6 @@ struct VirtIOBlockDataPlane {
|
|||||||
bool stopping;
|
bool stopping;
|
||||||
|
|
||||||
VirtIOBlkConf *blk;
|
VirtIOBlkConf *blk;
|
||||||
int fd; /* image file descriptor */
|
|
||||||
|
|
||||||
VirtIODevice *vdev;
|
VirtIODevice *vdev;
|
||||||
Vring vring; /* virtqueue vring */
|
Vring vring; /* virtqueue vring */
|
||||||
@@ -61,16 +53,8 @@ struct VirtIOBlockDataPlane {
|
|||||||
IOThread *iothread;
|
IOThread *iothread;
|
||||||
IOThread internal_iothread_obj;
|
IOThread internal_iothread_obj;
|
||||||
AioContext *ctx;
|
AioContext *ctx;
|
||||||
EventNotifier io_notifier; /* Linux AIO completion */
|
|
||||||
EventNotifier host_notifier; /* doorbell */
|
EventNotifier host_notifier; /* doorbell */
|
||||||
|
|
||||||
IOQueue ioqueue; /* Linux AIO queue (should really be per
|
|
||||||
IOThread) */
|
|
||||||
VirtIOBlockRequest requests[REQ_MAX]; /* pool of requests, managed by the
|
|
||||||
queue */
|
|
||||||
|
|
||||||
unsigned int num_reqs;
|
|
||||||
|
|
||||||
/* Operation blocker on BDS */
|
/* Operation blocker on BDS */
|
||||||
Error *blocker;
|
Error *blocker;
|
||||||
};
|
};
|
||||||
@@ -85,33 +69,28 @@ static void notify_guest(VirtIOBlockDataPlane *s)
|
|||||||
event_notifier_set(s->guest_notifier);
|
event_notifier_set(s->guest_notifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void complete_request(struct iocb *iocb, ssize_t ret, void *opaque)
|
static void complete_rdwr(void *opaque, int ret)
|
||||||
{
|
{
|
||||||
VirtIOBlockDataPlane *s = opaque;
|
VirtIOBlockRequest *req = opaque;
|
||||||
VirtIOBlockRequest *req = container_of(iocb, VirtIOBlockRequest, iocb);
|
|
||||||
struct virtio_blk_inhdr hdr;
|
struct virtio_blk_inhdr hdr;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (likely(ret >= 0)) {
|
if (likely(ret == 0)) {
|
||||||
hdr.status = VIRTIO_BLK_S_OK;
|
hdr.status = VIRTIO_BLK_S_OK;
|
||||||
len = ret;
|
len = req->qiov.size;
|
||||||
} else {
|
} else {
|
||||||
hdr.status = VIRTIO_BLK_S_IOERR;
|
hdr.status = VIRTIO_BLK_S_IOERR;
|
||||||
len = 0;
|
len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_virtio_blk_data_plane_complete_request(s, req->elem->index, ret);
|
trace_virtio_blk_data_plane_complete_request(req->s, req->elem->index, ret);
|
||||||
|
|
||||||
if (req->read_qiov) {
|
if (req->read && req->bounce_iov.iov_base) {
|
||||||
assert(req->bounce_iov);
|
qemu_iovec_from_buf(&req->qiov, 0, req->bounce_iov.iov_base, len);
|
||||||
qemu_iovec_from_buf(req->read_qiov, 0, req->bounce_iov->iov_base, len);
|
|
||||||
qemu_iovec_destroy(req->read_qiov);
|
|
||||||
g_slice_free(QEMUIOVector, req->read_qiov);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->bounce_iov) {
|
if (req->bounce_iov.iov_base) {
|
||||||
qemu_vfree(req->bounce_iov->iov_base);
|
qemu_vfree(req->bounce_iov.iov_base);
|
||||||
g_slice_free(struct iovec, req->bounce_iov);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_iovec_from_buf(req->inhdr, 0, &hdr, sizeof(hdr));
|
qemu_iovec_from_buf(req->inhdr, 0, &hdr, sizeof(hdr));
|
||||||
@@ -122,9 +101,9 @@ static void complete_request(struct iocb *iocb, ssize_t ret, void *opaque)
|
|||||||
* written to, but for virtio-blk it seems to be the number of bytes
|
* written to, but for virtio-blk it seems to be the number of bytes
|
||||||
* transferred plus the status bytes.
|
* transferred plus the status bytes.
|
||||||
*/
|
*/
|
||||||
vring_push(&s->vring, req->elem, len + sizeof(hdr));
|
vring_push(&req->s->vring, req->elem, len + sizeof(hdr));
|
||||||
req->elem = NULL;
|
notify_guest(req->s);
|
||||||
s->num_reqs--;
|
g_slice_free(VirtIOBlockRequest, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void complete_request_early(VirtIOBlockDataPlane *s, VirtQueueElement *elem,
|
static void complete_request_early(VirtIOBlockDataPlane *s, VirtQueueElement *elem,
|
||||||
@@ -155,51 +134,87 @@ static void do_get_id_cmd(VirtIOBlockDataPlane *s,
|
|||||||
complete_request_early(s, elem, inhdr, VIRTIO_BLK_S_OK);
|
complete_request_early(s, elem, inhdr, VIRTIO_BLK_S_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_rdwr_cmd(VirtIOBlockDataPlane *s, bool read,
|
static void do_rdwr_cmd(VirtIOBlockDataPlane *s, bool read,
|
||||||
struct iovec *iov, unsigned iov_cnt,
|
struct iovec *iov, unsigned iov_cnt,
|
||||||
long long offset, VirtQueueElement *elem,
|
int64_t sector_num, VirtQueueElement *elem,
|
||||||
QEMUIOVector *inhdr)
|
QEMUIOVector *inhdr)
|
||||||
{
|
{
|
||||||
struct iocb *iocb;
|
VirtIOBlockRequest *req = g_slice_new0(VirtIOBlockRequest);
|
||||||
QEMUIOVector qiov;
|
QEMUIOVector *qiov;
|
||||||
struct iovec *bounce_iov = NULL;
|
int nb_sectors;
|
||||||
QEMUIOVector *read_qiov = NULL;
|
|
||||||
|
|
||||||
qemu_iovec_init_external(&qiov, iov, iov_cnt);
|
/* Fill in virtio block metadata needed for completion */
|
||||||
if (!bdrv_qiov_is_aligned(s->blk->conf.bs, &qiov)) {
|
req->s = s;
|
||||||
void *bounce_buffer = qemu_blockalign(s->blk->conf.bs, qiov.size);
|
req->elem = elem;
|
||||||
|
req->inhdr = inhdr;
|
||||||
|
req->read = read;
|
||||||
|
qemu_iovec_init_external(&req->qiov, iov, iov_cnt);
|
||||||
|
|
||||||
if (read) {
|
qiov = &req->qiov;
|
||||||
/* Need to copy back from bounce buffer on completion */
|
|
||||||
read_qiov = g_slice_new(QEMUIOVector);
|
if (!bdrv_qiov_is_aligned(s->blk->conf.bs, qiov)) {
|
||||||
qemu_iovec_init(read_qiov, iov_cnt);
|
void *bounce_buffer = qemu_blockalign(s->blk->conf.bs, qiov->size);
|
||||||
qemu_iovec_concat_iov(read_qiov, iov, iov_cnt, 0, qiov.size);
|
|
||||||
} else {
|
/* Populate bounce buffer with data for writes */
|
||||||
qemu_iovec_to_buf(&qiov, 0, bounce_buffer, qiov.size);
|
if (!read) {
|
||||||
|
qemu_iovec_to_buf(qiov, 0, bounce_buffer, qiov->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Redirect I/O to aligned bounce buffer */
|
/* Redirect I/O to aligned bounce buffer */
|
||||||
bounce_iov = g_slice_new(struct iovec);
|
req->bounce_iov.iov_base = bounce_buffer;
|
||||||
bounce_iov->iov_base = bounce_buffer;
|
req->bounce_iov.iov_len = qiov->size;
|
||||||
bounce_iov->iov_len = qiov.size;
|
qemu_iovec_init_external(&req->bounce_qiov, &req->bounce_iov, 1);
|
||||||
iov = bounce_iov;
|
qiov = &req->bounce_qiov;
|
||||||
iov_cnt = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iocb = ioq_rdwr(&s->ioqueue, read, iov, iov_cnt, offset);
|
nb_sectors = qiov->size / BDRV_SECTOR_SIZE;
|
||||||
|
|
||||||
/* Fill in virtio block metadata needed for completion */
|
if (read) {
|
||||||
VirtIOBlockRequest *req = container_of(iocb, VirtIOBlockRequest, iocb);
|
bdrv_aio_readv(s->blk->conf.bs, sector_num, qiov, nb_sectors,
|
||||||
req->elem = elem;
|
complete_rdwr, req);
|
||||||
req->inhdr = inhdr;
|
} else {
|
||||||
req->bounce_iov = bounce_iov;
|
bdrv_aio_writev(s->blk->conf.bs, sector_num, qiov, nb_sectors,
|
||||||
req->read_qiov = read_qiov;
|
complete_rdwr, req);
|
||||||
return 0;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process_request(IOQueue *ioq, VirtQueueElement *elem)
|
static void complete_flush(void *opaque, int ret)
|
||||||
|
{
|
||||||
|
VirtIOBlockRequest *req = opaque;
|
||||||
|
unsigned char status;
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
status = VIRTIO_BLK_S_OK;
|
||||||
|
} else {
|
||||||
|
status = VIRTIO_BLK_S_IOERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_request_early(req->s, req->elem, req->inhdr, status);
|
||||||
|
g_slice_free(VirtIOBlockRequest, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_flush_cmd(VirtIOBlockDataPlane *s, VirtQueueElement *elem,
|
||||||
|
QEMUIOVector *inhdr)
|
||||||
|
{
|
||||||
|
VirtIOBlockRequest *req = g_slice_new(VirtIOBlockRequest);
|
||||||
|
req->s = s;
|
||||||
|
req->elem = elem;
|
||||||
|
req->inhdr = inhdr;
|
||||||
|
|
||||||
|
bdrv_aio_flush(s->blk->conf.bs, complete_flush, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_scsi_cmd(VirtIOBlockDataPlane *s, VirtQueueElement *elem,
|
||||||
|
QEMUIOVector *inhdr)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = virtio_blk_handle_scsi_req(VIRTIO_BLK(s->vdev), elem);
|
||||||
|
complete_request_early(s, elem, inhdr, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int process_request(VirtIOBlockDataPlane *s, VirtQueueElement *elem)
|
||||||
{
|
{
|
||||||
VirtIOBlockDataPlane *s = container_of(ioq, VirtIOBlockDataPlane, ioqueue);
|
|
||||||
struct iovec *iov = elem->out_sg;
|
struct iovec *iov = elem->out_sg;
|
||||||
struct iovec *in_iov = elem->in_sg;
|
struct iovec *in_iov = elem->in_sg;
|
||||||
unsigned out_num = elem->out_num;
|
unsigned out_num = elem->out_num;
|
||||||
@@ -234,25 +249,23 @@ static int process_request(IOQueue *ioq, VirtQueueElement *elem)
|
|||||||
|
|
||||||
switch (outhdr.type) {
|
switch (outhdr.type) {
|
||||||
case VIRTIO_BLK_T_IN:
|
case VIRTIO_BLK_T_IN:
|
||||||
do_rdwr_cmd(s, true, in_iov, in_num, outhdr.sector * 512, elem, inhdr);
|
do_rdwr_cmd(s, true, in_iov, in_num,
|
||||||
|
outhdr.sector * 512 / BDRV_SECTOR_SIZE,
|
||||||
|
elem, inhdr);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case VIRTIO_BLK_T_OUT:
|
case VIRTIO_BLK_T_OUT:
|
||||||
do_rdwr_cmd(s, false, iov, out_num, outhdr.sector * 512, elem, inhdr);
|
do_rdwr_cmd(s, false, iov, out_num,
|
||||||
|
outhdr.sector * 512 / BDRV_SECTOR_SIZE,
|
||||||
|
elem, inhdr);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case VIRTIO_BLK_T_SCSI_CMD:
|
case VIRTIO_BLK_T_SCSI_CMD:
|
||||||
/* TODO support SCSI commands */
|
do_scsi_cmd(s, elem, inhdr);
|
||||||
complete_request_early(s, elem, inhdr, VIRTIO_BLK_S_UNSUPP);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case VIRTIO_BLK_T_FLUSH:
|
case VIRTIO_BLK_T_FLUSH:
|
||||||
/* TODO fdsync not supported by Linux AIO, do it synchronously here! */
|
do_flush_cmd(s, elem, inhdr);
|
||||||
if (qemu_fdatasync(s->fd) < 0) {
|
|
||||||
complete_request_early(s, elem, inhdr, VIRTIO_BLK_S_IOERR);
|
|
||||||
} else {
|
|
||||||
complete_request_early(s, elem, inhdr, VIRTIO_BLK_S_OK);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case VIRTIO_BLK_T_GET_ID:
|
case VIRTIO_BLK_T_GET_ID:
|
||||||
@@ -274,7 +287,6 @@ static void handle_notify(EventNotifier *e)
|
|||||||
|
|
||||||
VirtQueueElement *elem;
|
VirtQueueElement *elem;
|
||||||
int ret;
|
int ret;
|
||||||
unsigned int num_queued;
|
|
||||||
|
|
||||||
event_notifier_test_and_clear(&s->host_notifier);
|
event_notifier_test_and_clear(&s->host_notifier);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@@ -291,7 +303,7 @@ static void handle_notify(EventNotifier *e)
|
|||||||
trace_virtio_blk_data_plane_process_request(s, elem->out_num,
|
trace_virtio_blk_data_plane_process_request(s, elem->out_num,
|
||||||
elem->in_num, elem->index);
|
elem->in_num, elem->index);
|
||||||
|
|
||||||
if (process_request(&s->ioqueue, elem) < 0) {
|
if (process_request(s, elem) < 0) {
|
||||||
vring_set_broken(&s->vring);
|
vring_set_broken(&s->vring);
|
||||||
vring_free_element(elem);
|
vring_free_element(elem);
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
@@ -306,44 +318,10 @@ static void handle_notify(EventNotifier *e)
|
|||||||
if (vring_enable_notification(s->vdev, &s->vring)) {
|
if (vring_enable_notification(s->vdev, &s->vring)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else { /* ret == -ENOBUFS or fatal error, iovecs[] is depleted */
|
} else { /* fatal error */
|
||||||
/* Since there are no iovecs[] left, stop processing for now. Do
|
|
||||||
* not re-enable guest->host notifies since the I/O completion
|
|
||||||
* handler knows to check for more vring descriptors anyway.
|
|
||||||
*/
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
num_queued = ioq_num_queued(&s->ioqueue);
|
|
||||||
if (num_queued > 0) {
|
|
||||||
s->num_reqs += num_queued;
|
|
||||||
|
|
||||||
int rc = ioq_submit(&s->ioqueue);
|
|
||||||
if (unlikely(rc < 0)) {
|
|
||||||
fprintf(stderr, "ioq_submit failed %d\n", rc);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_io(EventNotifier *e)
|
|
||||||
{
|
|
||||||
VirtIOBlockDataPlane *s = container_of(e, VirtIOBlockDataPlane,
|
|
||||||
io_notifier);
|
|
||||||
|
|
||||||
event_notifier_test_and_clear(&s->io_notifier);
|
|
||||||
if (ioq_run_completion(&s->ioqueue, complete_request, s) > 0) {
|
|
||||||
notify_guest(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If there were more requests than iovecs, the vring will not be empty yet
|
|
||||||
* so check again. There should now be enough resources to process more
|
|
||||||
* requests.
|
|
||||||
*/
|
|
||||||
if (unlikely(vring_more_avail(&s->vring))) {
|
|
||||||
handle_notify(&s->host_notifier);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Context: QEMU global mutex held */
|
/* Context: QEMU global mutex held */
|
||||||
@@ -352,7 +330,6 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
|
|||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
VirtIOBlockDataPlane *s;
|
VirtIOBlockDataPlane *s;
|
||||||
int fd;
|
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
*dataplane = NULL;
|
*dataplane = NULL;
|
||||||
@@ -361,18 +338,6 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blk->scsi) {
|
|
||||||
error_setg(errp,
|
|
||||||
"device is incompatible with x-data-plane, use scsi=off");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blk->config_wce) {
|
|
||||||
error_setg(errp, "device is incompatible with x-data-plane, "
|
|
||||||
"use config-wce=off");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If dataplane is (re-)enabled while the guest is running there could be
|
/* If dataplane is (re-)enabled while the guest is running there could be
|
||||||
* block jobs that can conflict.
|
* block jobs that can conflict.
|
||||||
*/
|
*/
|
||||||
@@ -383,16 +348,8 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = raw_get_aio_fd(blk->conf.bs);
|
|
||||||
if (fd < 0) {
|
|
||||||
error_setg(errp, "drive is incompatible with x-data-plane, "
|
|
||||||
"use format=raw,cache=none,aio=native");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
s = g_new0(VirtIOBlockDataPlane, 1);
|
s = g_new0(VirtIOBlockDataPlane, 1);
|
||||||
s->vdev = vdev;
|
s->vdev = vdev;
|
||||||
s->fd = fd;
|
|
||||||
s->blk = blk;
|
s->blk = blk;
|
||||||
|
|
||||||
if (blk->iothread) {
|
if (blk->iothread) {
|
||||||
@@ -437,7 +394,6 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
|
|||||||
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s->vdev)));
|
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s->vdev)));
|
||||||
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
|
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
|
||||||
VirtQueue *vq;
|
VirtQueue *vq;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (s->started) {
|
if (s->started) {
|
||||||
return;
|
return;
|
||||||
@@ -470,24 +426,18 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
|
|||||||
}
|
}
|
||||||
s->host_notifier = *virtio_queue_get_host_notifier(vq);
|
s->host_notifier = *virtio_queue_get_host_notifier(vq);
|
||||||
|
|
||||||
/* Set up ioqueue */
|
|
||||||
ioq_init(&s->ioqueue, s->fd, REQ_MAX);
|
|
||||||
for (i = 0; i < ARRAY_SIZE(s->requests); i++) {
|
|
||||||
ioq_put_iocb(&s->ioqueue, &s->requests[i].iocb);
|
|
||||||
}
|
|
||||||
s->io_notifier = *ioq_get_notifier(&s->ioqueue);
|
|
||||||
|
|
||||||
s->starting = false;
|
s->starting = false;
|
||||||
s->started = true;
|
s->started = true;
|
||||||
trace_virtio_blk_data_plane_start(s);
|
trace_virtio_blk_data_plane_start(s);
|
||||||
|
|
||||||
|
bdrv_set_aio_context(s->blk->conf.bs, s->ctx);
|
||||||
|
|
||||||
/* Kick right away to begin processing requests already in vring */
|
/* Kick right away to begin processing requests already in vring */
|
||||||
event_notifier_set(virtio_queue_get_host_notifier(vq));
|
event_notifier_set(virtio_queue_get_host_notifier(vq));
|
||||||
|
|
||||||
/* Get this show started by hooking up our callbacks */
|
/* Get this show started by hooking up our callbacks */
|
||||||
aio_context_acquire(s->ctx);
|
aio_context_acquire(s->ctx);
|
||||||
aio_set_event_notifier(s->ctx, &s->host_notifier, handle_notify);
|
aio_set_event_notifier(s->ctx, &s->host_notifier, handle_notify);
|
||||||
aio_set_event_notifier(s->ctx, &s->io_notifier, handle_io);
|
|
||||||
aio_context_release(s->ctx);
|
aio_context_release(s->ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,13 +457,8 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
|
|||||||
/* Stop notifications for new requests from guest */
|
/* Stop notifications for new requests from guest */
|
||||||
aio_set_event_notifier(s->ctx, &s->host_notifier, NULL);
|
aio_set_event_notifier(s->ctx, &s->host_notifier, NULL);
|
||||||
|
|
||||||
/* Complete pending requests */
|
/* Drain and switch bs back to the QEMU main loop */
|
||||||
while (s->num_reqs > 0) {
|
bdrv_set_aio_context(s->blk->conf.bs, qemu_get_aio_context());
|
||||||
aio_poll(s->ctx, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Stop ioq callbacks (there are no pending requests left) */
|
|
||||||
aio_set_event_notifier(s->ctx, &s->io_notifier, NULL);
|
|
||||||
|
|
||||||
aio_context_release(s->ctx);
|
aio_context_release(s->ctx);
|
||||||
|
|
||||||
@@ -522,7 +467,6 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
|
|||||||
*/
|
*/
|
||||||
vring_teardown(&s->vring, s->vdev, 0);
|
vring_teardown(&s->vring, s->vdev, 0);
|
||||||
|
|
||||||
ioq_cleanup(&s->ioqueue);
|
|
||||||
k->set_host_notifier(qbus->parent, 0, false);
|
k->set_host_notifier(qbus->parent, 0, false);
|
||||||
|
|
||||||
/* Clean up guest notifier (irq) */
|
/* Clean up guest notifier (irq) */
|
||||||
|
|||||||
@@ -672,8 +672,7 @@ static const VMStateDescription vmstate_fdrive_media_changed = {
|
|||||||
.name = "fdrive/media_changed",
|
.name = "fdrive/media_changed",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.minimum_version_id_old = 1,
|
.fields = (VMStateField[]) {
|
||||||
.fields = (VMStateField[]) {
|
|
||||||
VMSTATE_UINT8(media_changed, FDrive),
|
VMSTATE_UINT8(media_changed, FDrive),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
}
|
}
|
||||||
@@ -690,8 +689,7 @@ static const VMStateDescription vmstate_fdrive_media_rate = {
|
|||||||
.name = "fdrive/media_rate",
|
.name = "fdrive/media_rate",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.minimum_version_id_old = 1,
|
.fields = (VMStateField[]) {
|
||||||
.fields = (VMStateField[]) {
|
|
||||||
VMSTATE_UINT8(media_rate, FDrive),
|
VMSTATE_UINT8(media_rate, FDrive),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
}
|
}
|
||||||
@@ -701,8 +699,7 @@ static const VMStateDescription vmstate_fdrive = {
|
|||||||
.name = "fdrive",
|
.name = "fdrive",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.minimum_version_id_old = 1,
|
.fields = (VMStateField[]) {
|
||||||
.fields = (VMStateField[]) {
|
|
||||||
VMSTATE_UINT8(head, FDrive),
|
VMSTATE_UINT8(head, FDrive),
|
||||||
VMSTATE_UINT8(track, FDrive),
|
VMSTATE_UINT8(track, FDrive),
|
||||||
VMSTATE_UINT8(sect, FDrive),
|
VMSTATE_UINT8(sect, FDrive),
|
||||||
@@ -741,10 +738,9 @@ static const VMStateDescription vmstate_fdc = {
|
|||||||
.name = "fdc",
|
.name = "fdc",
|
||||||
.version_id = 2,
|
.version_id = 2,
|
||||||
.minimum_version_id = 2,
|
.minimum_version_id = 2,
|
||||||
.minimum_version_id_old = 2,
|
|
||||||
.pre_save = fdc_pre_save,
|
.pre_save = fdc_pre_save,
|
||||||
.post_load = fdc_post_load,
|
.post_load = fdc_post_load,
|
||||||
.fields = (VMStateField []) {
|
.fields = (VMStateField[]) {
|
||||||
/* Controller State */
|
/* Controller State */
|
||||||
VMSTATE_UINT8(sra, FDCtrl),
|
VMSTATE_UINT8(sra, FDCtrl),
|
||||||
VMSTATE_UINT8(srb, FDCtrl),
|
VMSTATE_UINT8(srb, FDCtrl),
|
||||||
@@ -2209,7 +2205,7 @@ static const VMStateDescription vmstate_isa_fdc ={
|
|||||||
.name = "fdc",
|
.name = "fdc",
|
||||||
.version_id = 2,
|
.version_id = 2,
|
||||||
.minimum_version_id = 2,
|
.minimum_version_id = 2,
|
||||||
.fields = (VMStateField []) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_STRUCT(state, FDCtrlISABus, 0, vmstate_fdc, FDCtrl),
|
VMSTATE_STRUCT(state, FDCtrlISABus, 0, vmstate_fdc, FDCtrl),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
}
|
}
|
||||||
@@ -2251,7 +2247,7 @@ static const VMStateDescription vmstate_sysbus_fdc ={
|
|||||||
.name = "fdc",
|
.name = "fdc",
|
||||||
.version_id = 2,
|
.version_id = 2,
|
||||||
.minimum_version_id = 2,
|
.minimum_version_id = 2,
|
||||||
.fields = (VMStateField []) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_STRUCT(state, FDCtrlSysBus, 0, vmstate_fdc, FDCtrl),
|
VMSTATE_STRUCT(state, FDCtrlSysBus, 0, vmstate_fdc, FDCtrl),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -335,9 +335,7 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
|
|||||||
dp, 1) < 0;
|
dp, 1) < 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dp) {
|
g_free(dp);
|
||||||
g_free(dp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ typedef struct VirtIOBlockReq
|
|||||||
VirtQueueElement elem;
|
VirtQueueElement elem;
|
||||||
struct virtio_blk_inhdr *in;
|
struct virtio_blk_inhdr *in;
|
||||||
struct virtio_blk_outhdr *out;
|
struct virtio_blk_outhdr *out;
|
||||||
struct virtio_scsi_inhdr *scsi;
|
|
||||||
QEMUIOVector qiov;
|
QEMUIOVector qiov;
|
||||||
struct VirtIOBlockReq *next;
|
struct VirtIOBlockReq *next;
|
||||||
BlockAcctCookie acct;
|
BlockAcctCookie acct;
|
||||||
@@ -125,13 +124,15 @@ static VirtIOBlockReq *virtio_blk_get_request(VirtIOBlock *s)
|
|||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
|
int virtio_blk_handle_scsi_req(VirtIOBlock *blk,
|
||||||
|
VirtQueueElement *elem)
|
||||||
{
|
{
|
||||||
#ifdef __linux__
|
|
||||||
int ret;
|
|
||||||
int i;
|
|
||||||
#endif
|
|
||||||
int status = VIRTIO_BLK_S_OK;
|
int status = VIRTIO_BLK_S_OK;
|
||||||
|
struct virtio_scsi_inhdr *scsi = NULL;
|
||||||
|
#ifdef __linux__
|
||||||
|
int i;
|
||||||
|
struct sg_io_hdr hdr;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We require at least one output segment each for the virtio_blk_outhdr
|
* We require at least one output segment each for the virtio_blk_outhdr
|
||||||
@@ -140,19 +141,18 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
|
|||||||
* We also at least require the virtio_blk_inhdr, the virtio_scsi_inhdr
|
* We also at least require the virtio_blk_inhdr, the virtio_scsi_inhdr
|
||||||
* and the sense buffer pointer in the input segments.
|
* and the sense buffer pointer in the input segments.
|
||||||
*/
|
*/
|
||||||
if (req->elem.out_num < 2 || req->elem.in_num < 3) {
|
if (elem->out_num < 2 || elem->in_num < 3) {
|
||||||
virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
|
status = VIRTIO_BLK_S_IOERR;
|
||||||
g_free(req);
|
goto fail;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The scsi inhdr is placed in the second-to-last input segment, just
|
* The scsi inhdr is placed in the second-to-last input segment, just
|
||||||
* before the regular inhdr.
|
* before the regular inhdr.
|
||||||
*/
|
*/
|
||||||
req->scsi = (void *)req->elem.in_sg[req->elem.in_num - 2].iov_base;
|
scsi = (void *)elem->in_sg[elem->in_num - 2].iov_base;
|
||||||
|
|
||||||
if (!req->dev->blk.scsi) {
|
if (!blk->blk.scsi) {
|
||||||
status = VIRTIO_BLK_S_UNSUPP;
|
status = VIRTIO_BLK_S_UNSUPP;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@@ -160,43 +160,42 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
|
|||||||
/*
|
/*
|
||||||
* No support for bidirection commands yet.
|
* No support for bidirection commands yet.
|
||||||
*/
|
*/
|
||||||
if (req->elem.out_num > 2 && req->elem.in_num > 3) {
|
if (elem->out_num > 2 && elem->in_num > 3) {
|
||||||
status = VIRTIO_BLK_S_UNSUPP;
|
status = VIRTIO_BLK_S_UNSUPP;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
struct sg_io_hdr hdr;
|
|
||||||
memset(&hdr, 0, sizeof(struct sg_io_hdr));
|
memset(&hdr, 0, sizeof(struct sg_io_hdr));
|
||||||
hdr.interface_id = 'S';
|
hdr.interface_id = 'S';
|
||||||
hdr.cmd_len = req->elem.out_sg[1].iov_len;
|
hdr.cmd_len = elem->out_sg[1].iov_len;
|
||||||
hdr.cmdp = req->elem.out_sg[1].iov_base;
|
hdr.cmdp = elem->out_sg[1].iov_base;
|
||||||
hdr.dxfer_len = 0;
|
hdr.dxfer_len = 0;
|
||||||
|
|
||||||
if (req->elem.out_num > 2) {
|
if (elem->out_num > 2) {
|
||||||
/*
|
/*
|
||||||
* If there are more than the minimally required 2 output segments
|
* If there are more than the minimally required 2 output segments
|
||||||
* there is write payload starting from the third iovec.
|
* there is write payload starting from the third iovec.
|
||||||
*/
|
*/
|
||||||
hdr.dxfer_direction = SG_DXFER_TO_DEV;
|
hdr.dxfer_direction = SG_DXFER_TO_DEV;
|
||||||
hdr.iovec_count = req->elem.out_num - 2;
|
hdr.iovec_count = elem->out_num - 2;
|
||||||
|
|
||||||
for (i = 0; i < hdr.iovec_count; i++)
|
for (i = 0; i < hdr.iovec_count; i++)
|
||||||
hdr.dxfer_len += req->elem.out_sg[i + 2].iov_len;
|
hdr.dxfer_len += elem->out_sg[i + 2].iov_len;
|
||||||
|
|
||||||
hdr.dxferp = req->elem.out_sg + 2;
|
hdr.dxferp = elem->out_sg + 2;
|
||||||
|
|
||||||
} else if (req->elem.in_num > 3) {
|
} else if (elem->in_num > 3) {
|
||||||
/*
|
/*
|
||||||
* If we have more than 3 input segments the guest wants to actually
|
* If we have more than 3 input segments the guest wants to actually
|
||||||
* read data.
|
* read data.
|
||||||
*/
|
*/
|
||||||
hdr.dxfer_direction = SG_DXFER_FROM_DEV;
|
hdr.dxfer_direction = SG_DXFER_FROM_DEV;
|
||||||
hdr.iovec_count = req->elem.in_num - 3;
|
hdr.iovec_count = elem->in_num - 3;
|
||||||
for (i = 0; i < hdr.iovec_count; i++)
|
for (i = 0; i < hdr.iovec_count; i++)
|
||||||
hdr.dxfer_len += req->elem.in_sg[i].iov_len;
|
hdr.dxfer_len += elem->in_sg[i].iov_len;
|
||||||
|
|
||||||
hdr.dxferp = req->elem.in_sg;
|
hdr.dxferp = elem->in_sg;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Some SCSI commands don't actually transfer any data.
|
* Some SCSI commands don't actually transfer any data.
|
||||||
@@ -204,11 +203,11 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
|
|||||||
hdr.dxfer_direction = SG_DXFER_NONE;
|
hdr.dxfer_direction = SG_DXFER_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr.sbp = req->elem.in_sg[req->elem.in_num - 3].iov_base;
|
hdr.sbp = elem->in_sg[elem->in_num - 3].iov_base;
|
||||||
hdr.mx_sb_len = req->elem.in_sg[req->elem.in_num - 3].iov_len;
|
hdr.mx_sb_len = elem->in_sg[elem->in_num - 3].iov_len;
|
||||||
|
|
||||||
ret = bdrv_ioctl(req->dev->bs, SG_IO, &hdr);
|
status = bdrv_ioctl(blk->bs, SG_IO, &hdr);
|
||||||
if (ret) {
|
if (status) {
|
||||||
status = VIRTIO_BLK_S_UNSUPP;
|
status = VIRTIO_BLK_S_UNSUPP;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@@ -224,23 +223,31 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
|
|||||||
hdr.status = CHECK_CONDITION;
|
hdr.status = CHECK_CONDITION;
|
||||||
}
|
}
|
||||||
|
|
||||||
stl_p(&req->scsi->errors,
|
stl_p(&scsi->errors,
|
||||||
hdr.status | (hdr.msg_status << 8) |
|
hdr.status | (hdr.msg_status << 8) |
|
||||||
(hdr.host_status << 16) | (hdr.driver_status << 24));
|
(hdr.host_status << 16) | (hdr.driver_status << 24));
|
||||||
stl_p(&req->scsi->residual, hdr.resid);
|
stl_p(&scsi->residual, hdr.resid);
|
||||||
stl_p(&req->scsi->sense_len, hdr.sb_len_wr);
|
stl_p(&scsi->sense_len, hdr.sb_len_wr);
|
||||||
stl_p(&req->scsi->data_len, hdr.dxfer_len);
|
stl_p(&scsi->data_len, hdr.dxfer_len);
|
||||||
|
|
||||||
virtio_blk_req_complete(req, status);
|
return status;
|
||||||
g_free(req);
|
|
||||||
return;
|
|
||||||
#else
|
#else
|
||||||
abort();
|
abort();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
/* Just put anything nonzero so that the ioctl fails in the guest. */
|
/* Just put anything nonzero so that the ioctl fails in the guest. */
|
||||||
stl_p(&req->scsi->errors, 255);
|
if (scsi) {
|
||||||
|
stl_p(&scsi->errors, 255);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = virtio_blk_handle_scsi_req(req->dev, &req->elem);
|
||||||
virtio_blk_req_complete(req, status);
|
virtio_blk_req_complete(req, status);
|
||||||
g_free(req);
|
g_free(req);
|
||||||
}
|
}
|
||||||
@@ -487,12 +494,12 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
|
|||||||
|
|
||||||
bdrv_get_geometry(s->bs, &capacity);
|
bdrv_get_geometry(s->bs, &capacity);
|
||||||
memset(&blkcfg, 0, sizeof(blkcfg));
|
memset(&blkcfg, 0, sizeof(blkcfg));
|
||||||
stq_raw(&blkcfg.capacity, capacity);
|
stq_p(&blkcfg.capacity, capacity);
|
||||||
stl_raw(&blkcfg.seg_max, 128 - 2);
|
stl_p(&blkcfg.seg_max, 128 - 2);
|
||||||
stw_raw(&blkcfg.cylinders, s->conf->cyls);
|
stw_p(&blkcfg.cylinders, s->conf->cyls);
|
||||||
stl_raw(&blkcfg.blk_size, blk_size);
|
stl_p(&blkcfg.blk_size, blk_size);
|
||||||
stw_raw(&blkcfg.min_io_size, s->conf->min_io_size / blk_size);
|
stw_p(&blkcfg.min_io_size, s->conf->min_io_size / blk_size);
|
||||||
stw_raw(&blkcfg.opt_io_size, s->conf->opt_io_size / blk_size);
|
stw_p(&blkcfg.opt_io_size, s->conf->opt_io_size / blk_size);
|
||||||
blkcfg.heads = s->conf->heads;
|
blkcfg.heads = s->conf->heads;
|
||||||
/*
|
/*
|
||||||
* We must ensure that the block device capacity is a multiple of
|
* We must ensure that the block device capacity is a multiple of
|
||||||
@@ -523,7 +530,10 @@ static void virtio_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
|
|||||||
struct virtio_blk_config blkcfg;
|
struct virtio_blk_config blkcfg;
|
||||||
|
|
||||||
memcpy(&blkcfg, config, sizeof(blkcfg));
|
memcpy(&blkcfg, config, sizeof(blkcfg));
|
||||||
|
|
||||||
|
aio_context_acquire(bdrv_get_aio_context(s->bs));
|
||||||
bdrv_set_enable_write_cache(s->bs, blkcfg.wce != 0);
|
bdrv_set_enable_write_cache(s->bs, blkcfg.wce != 0);
|
||||||
|
aio_context_release(bdrv_get_aio_context(s->bs));
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
|
static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
|
||||||
@@ -582,7 +592,10 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
|
|||||||
* s->bs would erroneously be placed in writethrough mode.
|
* s->bs would erroneously be placed in writethrough mode.
|
||||||
*/
|
*/
|
||||||
if (!(features & (1 << VIRTIO_BLK_F_CONFIG_WCE))) {
|
if (!(features & (1 << VIRTIO_BLK_F_CONFIG_WCE))) {
|
||||||
bdrv_set_enable_write_cache(s->bs, !!(features & (1 << VIRTIO_BLK_F_WCE)));
|
aio_context_acquire(bdrv_get_aio_context(s->bs));
|
||||||
|
bdrv_set_enable_write_cache(s->bs,
|
||||||
|
!!(features & (1 << VIRTIO_BLK_F_WCE)));
|
||||||
|
aio_context_release(bdrv_get_aio_context(s->bs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -660,8 +660,7 @@ static const VMStateDescription vmstate_escc_chn = {
|
|||||||
.name ="escc_chn",
|
.name ="escc_chn",
|
||||||
.version_id = 2,
|
.version_id = 2,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.minimum_version_id_old = 1,
|
.fields = (VMStateField[]) {
|
||||||
.fields = (VMStateField []) {
|
|
||||||
VMSTATE_UINT32(vmstate_dummy, ChannelState),
|
VMSTATE_UINT32(vmstate_dummy, ChannelState),
|
||||||
VMSTATE_UINT32(reg, ChannelState),
|
VMSTATE_UINT32(reg, ChannelState),
|
||||||
VMSTATE_UINT32(rxint, ChannelState),
|
VMSTATE_UINT32(rxint, ChannelState),
|
||||||
@@ -680,8 +679,7 @@ static const VMStateDescription vmstate_escc = {
|
|||||||
.name ="escc",
|
.name ="escc",
|
||||||
.version_id = 2,
|
.version_id = 2,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.minimum_version_id_old = 1,
|
.fields = (VMStateField[]) {
|
||||||
.fields = (VMStateField []) {
|
|
||||||
VMSTATE_STRUCT_ARRAY(chn, ESCCState, 2, 2, vmstate_escc_chn,
|
VMSTATE_STRUCT_ARRAY(chn, ESCCState, 2, 2, vmstate_escc_chn,
|
||||||
ChannelState),
|
ChannelState),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
typedef struct PCISerialState {
|
typedef struct PCISerialState {
|
||||||
PCIDevice dev;
|
PCIDevice dev;
|
||||||
SerialState state;
|
SerialState state;
|
||||||
|
uint8_t prog_if;
|
||||||
} PCISerialState;
|
} PCISerialState;
|
||||||
|
|
||||||
typedef struct PCIMultiSerialState {
|
typedef struct PCIMultiSerialState {
|
||||||
@@ -44,6 +45,7 @@ typedef struct PCIMultiSerialState {
|
|||||||
SerialState state[PCI_SERIAL_MAX_PORTS];
|
SerialState state[PCI_SERIAL_MAX_PORTS];
|
||||||
uint32_t level[PCI_SERIAL_MAX_PORTS];
|
uint32_t level[PCI_SERIAL_MAX_PORTS];
|
||||||
qemu_irq *irqs;
|
qemu_irq *irqs;
|
||||||
|
uint8_t prog_if;
|
||||||
} PCIMultiSerialState;
|
} PCIMultiSerialState;
|
||||||
|
|
||||||
static int serial_pci_init(PCIDevice *dev)
|
static int serial_pci_init(PCIDevice *dev)
|
||||||
@@ -60,6 +62,7 @@ static int serial_pci_init(PCIDevice *dev)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pci->dev.config[PCI_CLASS_PROG] = pci->prog_if;
|
||||||
pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
|
pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
|
||||||
s->irq = pci_allocate_irq(&pci->dev);
|
s->irq = pci_allocate_irq(&pci->dev);
|
||||||
|
|
||||||
@@ -101,6 +104,7 @@ static int multi_serial_pci_init(PCIDevice *dev)
|
|||||||
assert(pci->ports > 0);
|
assert(pci->ports > 0);
|
||||||
assert(pci->ports <= PCI_SERIAL_MAX_PORTS);
|
assert(pci->ports <= PCI_SERIAL_MAX_PORTS);
|
||||||
|
|
||||||
|
pci->dev.config[PCI_CLASS_PROG] = pci->prog_if;
|
||||||
pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
|
pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
|
||||||
memory_region_init(&pci->iobar, OBJECT(pci), "multiserial", 8 * pci->ports);
|
memory_region_init(&pci->iobar, OBJECT(pci), "multiserial", 8 * pci->ports);
|
||||||
pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->iobar);
|
pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->iobar);
|
||||||
@@ -155,7 +159,7 @@ static const VMStateDescription vmstate_pci_serial = {
|
|||||||
.name = "pci-serial",
|
.name = "pci-serial",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.fields = (VMStateField[]) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_PCI_DEVICE(dev, PCISerialState),
|
VMSTATE_PCI_DEVICE(dev, PCISerialState),
|
||||||
VMSTATE_STRUCT(state, PCISerialState, 0, vmstate_serial, SerialState),
|
VMSTATE_STRUCT(state, PCISerialState, 0, vmstate_serial, SerialState),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
@@ -166,7 +170,7 @@ static const VMStateDescription vmstate_pci_multi_serial = {
|
|||||||
.name = "pci-serial-multi",
|
.name = "pci-serial-multi",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.fields = (VMStateField[]) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_PCI_DEVICE(dev, PCIMultiSerialState),
|
VMSTATE_PCI_DEVICE(dev, PCIMultiSerialState),
|
||||||
VMSTATE_STRUCT_ARRAY(state, PCIMultiSerialState, PCI_SERIAL_MAX_PORTS,
|
VMSTATE_STRUCT_ARRAY(state, PCIMultiSerialState, PCI_SERIAL_MAX_PORTS,
|
||||||
0, vmstate_serial, SerialState),
|
0, vmstate_serial, SerialState),
|
||||||
@@ -177,12 +181,14 @@ static const VMStateDescription vmstate_pci_multi_serial = {
|
|||||||
|
|
||||||
static Property serial_pci_properties[] = {
|
static Property serial_pci_properties[] = {
|
||||||
DEFINE_PROP_CHR("chardev", PCISerialState, state.chr),
|
DEFINE_PROP_CHR("chardev", PCISerialState, state.chr),
|
||||||
|
DEFINE_PROP_UINT8("prog_if", PCISerialState, prog_if, 0x02),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
static Property multi_2x_serial_pci_properties[] = {
|
static Property multi_2x_serial_pci_properties[] = {
|
||||||
DEFINE_PROP_CHR("chardev1", PCIMultiSerialState, state[0].chr),
|
DEFINE_PROP_CHR("chardev1", PCIMultiSerialState, state[0].chr),
|
||||||
DEFINE_PROP_CHR("chardev2", PCIMultiSerialState, state[1].chr),
|
DEFINE_PROP_CHR("chardev2", PCIMultiSerialState, state[1].chr),
|
||||||
|
DEFINE_PROP_UINT8("prog_if", PCIMultiSerialState, prog_if, 0x02),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -191,6 +197,7 @@ static Property multi_4x_serial_pci_properties[] = {
|
|||||||
DEFINE_PROP_CHR("chardev2", PCIMultiSerialState, state[1].chr),
|
DEFINE_PROP_CHR("chardev2", PCIMultiSerialState, state[1].chr),
|
||||||
DEFINE_PROP_CHR("chardev3", PCIMultiSerialState, state[2].chr),
|
DEFINE_PROP_CHR("chardev3", PCIMultiSerialState, state[2].chr),
|
||||||
DEFINE_PROP_CHR("chardev4", PCIMultiSerialState, state[3].chr),
|
DEFINE_PROP_CHR("chardev4", PCIMultiSerialState, state[3].chr),
|
||||||
|
DEFINE_PROP_UINT8("prog_if", PCIMultiSerialState, prog_if, 0x02),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -602,7 +602,7 @@ const VMStateDescription vmstate_serial = {
|
|||||||
.minimum_version_id = 2,
|
.minimum_version_id = 2,
|
||||||
.pre_save = serial_pre_save,
|
.pre_save = serial_pre_save,
|
||||||
.post_load = serial_post_load,
|
.post_load = serial_post_load,
|
||||||
.fields = (VMStateField []) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_UINT16_V(divider, SerialState, 2),
|
VMSTATE_UINT16_V(divider, SerialState, 2),
|
||||||
VMSTATE_UINT8(rbr, SerialState),
|
VMSTATE_UINT8(rbr, SerialState),
|
||||||
VMSTATE_UINT8(ier, SerialState),
|
VMSTATE_UINT8(ier, SerialState),
|
||||||
|
|||||||
@@ -148,8 +148,7 @@ static const VMStateDescription vmstate_spapr_vty = {
|
|||||||
.name = "spapr_vty",
|
.name = "spapr_vty",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.minimum_version_id_old = 1,
|
.fields = (VMStateField[]) {
|
||||||
.fields = (VMStateField []) {
|
|
||||||
VMSTATE_SPAPR_VIO(sdev, VIOsPAPRVTYDevice),
|
VMSTATE_SPAPR_VIO(sdev, VIOsPAPRVTYDevice),
|
||||||
|
|
||||||
VMSTATE_UINT32(in, VIOsPAPRVTYDevice),
|
VMSTATE_UINT32(in, VIOsPAPRVTYDevice),
|
||||||
|
|||||||
@@ -87,6 +87,11 @@ static void uart_update_status(XilinxUARTLite *s)
|
|||||||
s->regs[R_STATUS] = r;
|
s->regs[R_STATUS] = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void xilinx_uartlite_reset(DeviceState *dev)
|
||||||
|
{
|
||||||
|
uart_update_status(XILINX_UARTLITE(dev));
|
||||||
|
}
|
||||||
|
|
||||||
static uint64_t
|
static uint64_t
|
||||||
uart_read(void *opaque, hwaddr addr, unsigned int size)
|
uart_read(void *opaque, hwaddr addr, unsigned int size)
|
||||||
{
|
{
|
||||||
@@ -196,34 +201,39 @@ static void uart_event(void *opaque, int event)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xilinx_uartlite_init(SysBusDevice *dev)
|
static void xilinx_uartlite_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
XilinxUARTLite *s = XILINX_UARTLITE(dev);
|
XilinxUARTLite *s = XILINX_UARTLITE(dev);
|
||||||
|
|
||||||
sysbus_init_irq(dev, &s->irq);
|
|
||||||
|
|
||||||
uart_update_status(s);
|
|
||||||
memory_region_init_io(&s->mmio, OBJECT(s), &uart_ops, s,
|
|
||||||
"xlnx.xps-uartlite", R_MAX * 4);
|
|
||||||
sysbus_init_mmio(dev, &s->mmio);
|
|
||||||
|
|
||||||
s->chr = qemu_char_get_next_serial();
|
s->chr = qemu_char_get_next_serial();
|
||||||
if (s->chr)
|
if (s->chr)
|
||||||
qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
|
qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
static void xilinx_uartlite_init(Object *obj)
|
||||||
|
{
|
||||||
|
XilinxUARTLite *s = XILINX_UARTLITE(obj);
|
||||||
|
|
||||||
|
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
|
||||||
|
|
||||||
|
memory_region_init_io(&s->mmio, obj, &uart_ops, s,
|
||||||
|
"xlnx.xps-uartlite", R_MAX * 4);
|
||||||
|
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xilinx_uartlite_class_init(ObjectClass *klass, void *data)
|
static void xilinx_uartlite_class_init(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
|
|
||||||
sdc->init = xilinx_uartlite_init;
|
dc->reset = xilinx_uartlite_reset;
|
||||||
|
dc->realize = xilinx_uartlite_realize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo xilinx_uartlite_info = {
|
static const TypeInfo xilinx_uartlite_info = {
|
||||||
.name = TYPE_XILINX_UARTLITE,
|
.name = TYPE_XILINX_UARTLITE,
|
||||||
.parent = TYPE_SYS_BUS_DEVICE,
|
.parent = TYPE_SYS_BUS_DEVICE,
|
||||||
.instance_size = sizeof(XilinxUARTLite),
|
.instance_size = sizeof(XilinxUARTLite),
|
||||||
|
.instance_init = xilinx_uartlite_init,
|
||||||
.class_init = xilinx_uartlite_class_init,
|
.class_init = xilinx_uartlite_class_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -439,11 +439,27 @@ PropertyInfo qdev_prop_iothread = {
|
|||||||
static int qdev_add_one_global(QemuOpts *opts, void *opaque)
|
static int qdev_add_one_global(QemuOpts *opts, void *opaque)
|
||||||
{
|
{
|
||||||
GlobalProperty *g;
|
GlobalProperty *g;
|
||||||
|
ObjectClass *oc;
|
||||||
|
|
||||||
g = g_malloc0(sizeof(*g));
|
g = g_malloc0(sizeof(*g));
|
||||||
g->driver = qemu_opt_get(opts, "driver");
|
g->driver = qemu_opt_get(opts, "driver");
|
||||||
g->property = qemu_opt_get(opts, "property");
|
g->property = qemu_opt_get(opts, "property");
|
||||||
g->value = qemu_opt_get(opts, "value");
|
g->value = qemu_opt_get(opts, "value");
|
||||||
|
oc = object_class_by_name(g->driver);
|
||||||
|
if (oc) {
|
||||||
|
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||||
|
|
||||||
|
if (dc->hotpluggable) {
|
||||||
|
/* If hotpluggable then skip not_used checking. */
|
||||||
|
g->not_used = false;
|
||||||
|
} else {
|
||||||
|
/* Maybe a typo. */
|
||||||
|
g->not_used = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Maybe a typo. */
|
||||||
|
g->not_used = true;
|
||||||
|
}
|
||||||
qdev_prop_register_global(g);
|
qdev_prop_register_global(g);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -955,6 +955,23 @@ void qdev_prop_register_global_list(GlobalProperty *props)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int qdev_prop_check_global(void)
|
||||||
|
{
|
||||||
|
GlobalProperty *prop;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
QTAILQ_FOREACH(prop, &global_props, next) {
|
||||||
|
if (!prop->not_used) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ret = 1;
|
||||||
|
error_report("Warning: \"-global %s.%s=%s\" not used",
|
||||||
|
prop->driver, prop->property, prop->value);
|
||||||
|
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename,
|
void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
@@ -966,6 +983,7 @@ void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename,
|
|||||||
if (strcmp(typename, prop->driver) != 0) {
|
if (strcmp(typename, prop->driver) != 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
prop->not_used = false;
|
||||||
object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
|
object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
|
||||||
if (err != NULL) {
|
if (err != NULL) {
|
||||||
error_propagate(errp, err);
|
error_propagate(errp, err);
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ static uint64_t cg3_reg_read(void *opaque, hwaddr addr, unsigned size)
|
|||||||
/* monitor ID 6, board type = 1 (color) */
|
/* monitor ID 6, board type = 1 (color) */
|
||||||
val = s->regs[1] | CG3_SR_1152_900_76_B | CG3_SR_ID_COLOR;
|
val = s->regs[1] | CG3_SR_1152_900_76_B | CG3_SR_ID_COLOR;
|
||||||
break;
|
break;
|
||||||
case CG3_REG_FBC_CURSTART ... CG3_REG_SIZE:
|
case CG3_REG_FBC_CURSTART ... CG3_REG_SIZE - 1:
|
||||||
val = s->regs[addr - 0x10];
|
val = s->regs[addr - 0x10];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -247,7 +247,7 @@ static void cg3_reg_write(void *opaque, hwaddr addr, uint64_t val,
|
|||||||
qemu_irq_lower(s->irq);
|
qemu_irq_lower(s->irq);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CG3_REG_FBC_CURSTART ... CG3_REG_SIZE:
|
case CG3_REG_FBC_CURSTART ... CG3_REG_SIZE - 1:
|
||||||
s->regs[addr - 0x10] = val;
|
s->regs[addr - 0x10] = val;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -274,6 +274,20 @@ static const GraphicHwOps cg3_ops = {
|
|||||||
.gfx_update = cg3_update_display,
|
.gfx_update = cg3_update_display,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void cg3_initfn(Object *obj)
|
||||||
|
{
|
||||||
|
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
||||||
|
CG3State *s = CG3(obj);
|
||||||
|
|
||||||
|
memory_region_init_ram(&s->rom, NULL, "cg3.prom", FCODE_MAX_ROM_SIZE);
|
||||||
|
memory_region_set_readonly(&s->rom, true);
|
||||||
|
sysbus_init_mmio(sbd, &s->rom);
|
||||||
|
|
||||||
|
memory_region_init_io(&s->reg, NULL, &cg3_reg_ops, s, "cg3.reg",
|
||||||
|
CG3_REG_SIZE);
|
||||||
|
sysbus_init_mmio(sbd, &s->reg);
|
||||||
|
}
|
||||||
|
|
||||||
static void cg3_realizefn(DeviceState *dev, Error **errp)
|
static void cg3_realizefn(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||||
@@ -282,11 +296,7 @@ static void cg3_realizefn(DeviceState *dev, Error **errp)
|
|||||||
char *fcode_filename;
|
char *fcode_filename;
|
||||||
|
|
||||||
/* FCode ROM */
|
/* FCode ROM */
|
||||||
memory_region_init_ram(&s->rom, NULL, "cg3.prom", FCODE_MAX_ROM_SIZE);
|
|
||||||
vmstate_register_ram_global(&s->rom);
|
vmstate_register_ram_global(&s->rom);
|
||||||
memory_region_set_readonly(&s->rom, true);
|
|
||||||
sysbus_init_mmio(sbd, &s->rom);
|
|
||||||
|
|
||||||
fcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, CG3_ROM_FILE);
|
fcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, CG3_ROM_FILE);
|
||||||
if (fcode_filename) {
|
if (fcode_filename) {
|
||||||
ret = load_image_targphys(fcode_filename, s->prom_addr,
|
ret = load_image_targphys(fcode_filename, s->prom_addr,
|
||||||
@@ -296,10 +306,6 @@ static void cg3_realizefn(DeviceState *dev, Error **errp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memory_region_init_io(&s->reg, NULL, &cg3_reg_ops, s, "cg3.reg",
|
|
||||||
CG3_REG_SIZE);
|
|
||||||
sysbus_init_mmio(sbd, &s->reg);
|
|
||||||
|
|
||||||
memory_region_init_ram(&s->vram_mem, NULL, "cg3.vram", s->vram_size);
|
memory_region_init_ram(&s->vram_mem, NULL, "cg3.vram", s->vram_size);
|
||||||
vmstate_register_ram_global(&s->vram_mem);
|
vmstate_register_ram_global(&s->vram_mem);
|
||||||
sysbus_init_mmio(sbd, &s->vram_mem);
|
sysbus_init_mmio(sbd, &s->vram_mem);
|
||||||
@@ -374,6 +380,7 @@ static const TypeInfo cg3_info = {
|
|||||||
.name = TYPE_CG3,
|
.name = TYPE_CG3,
|
||||||
.parent = TYPE_SYS_BUS_DEVICE,
|
.parent = TYPE_SYS_BUS_DEVICE,
|
||||||
.instance_size = sizeof(CG3State),
|
.instance_size = sizeof(CG3State),
|
||||||
|
.instance_init = cg3_initfn,
|
||||||
.class_init = cg3_class_init,
|
.class_init = cg3_class_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user