Browse Source

trace: switch to modular code generation for sub-directories

Introduce rules in the top level Makefile that are able to generate
trace.[ch] files in every subdirectory which has a trace-events file.

The top level directory is handled specially, so instead of creating
trace.h, it creates trace-root.h. This allows sub-directories to
include the top level trace-root.h file, without ambiguity wrt to
the trace.g file in the current sub-dir.

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Message-id: 2017012516.31949-7-berrange@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
tags/v2.9.0-rc0
Daniel P. Berrange 2 years ago
parent
commit
0ab8ed18a6

+ 16
- 6
.gitignore View File

@@ -6,18 +6,12 @@
6 6
 /config.status
7 7
 /config-temp
8 8
 /trace-events-all
9
-/trace/generated-tracers.h
10
-/trace/generated-tracers.c
11
-/trace/generated-tracers-dtrace.h
12
-/trace/generated-tracers.dtrace
13 9
 /trace/generated-events.h
14 10
 /trace/generated-events.c
15 11
 /trace/generated-helpers-wrappers.h
16 12
 /trace/generated-helpers.h
17 13
 /trace/generated-helpers.c
18 14
 /trace/generated-tcg-tracers.h
19
-/trace/generated-ust-provider.h
20
-/trace/generated-ust.c
21 15
 /ui/shader/texture-blit-frag.h
22 16
 /ui/shader/texture-blit-vert.h
23 17
 *-timestamp
@@ -120,3 +114,19 @@ tags
120 114
 TAGS
121 115
 docker-src.*
122 116
 *~
117
+trace.h
118
+trace.c
119
+trace-ust.h
120
+trace-ust.h
121
+trace-dtrace.h
122
+trace-dtrace.dtrace
123
+trace-root.h
124
+trace-root.c
125
+trace-ust-root.h
126
+trace-ust-root.h
127
+trace-ust-all.h
128
+trace-ust-all.c
129
+trace-dtrace-root.h
130
+trace-dtrace-root.dtrace
131
+trace-ust-all.h
132
+trace-ust-all.c

+ 137
- 19
Makefile View File

@@ -56,25 +56,136 @@ GENERATED_SOURCES += qmp-marshal.c qapi-types.c qapi-visit.c qapi-event.c
56 56
 GENERATED_HEADERS += qmp-introspect.h
57 57
 GENERATED_SOURCES += qmp-introspect.c
58 58
 
59
-GENERATED_HEADERS += trace/generated-tracers.h
60
-ifeq ($(findstring dtrace,$(TRACE_BACKENDS)),dtrace)
61
-GENERATED_HEADERS += trace/generated-tracers-dtrace.h
62
-endif
63
-GENERATED_SOURCES += trace/generated-tracers.c
64
-
65 59
 GENERATED_HEADERS += trace/generated-tcg-tracers.h
66 60
 
67 61
 GENERATED_HEADERS += trace/generated-helpers-wrappers.h
68 62
 GENERATED_HEADERS += trace/generated-helpers.h
69 63
 GENERATED_SOURCES += trace/generated-helpers.c
70 64
 
71
-ifeq ($(findstring ust,$(TRACE_BACKENDS)),ust)
72
-GENERATED_HEADERS += trace/generated-ust-provider.h
73
-GENERATED_SOURCES += trace/generated-ust.c
65
+ifdef CONFIG_TRACE_UST
66
+GENERATED_HEADERS += trace-ust-all.h
67
+GENERATED_SOURCES += trace-ust-all.c
74 68
 endif
75 69
 
76 70
 GENERATED_HEADERS += module_block.h
77 71
 
72
+TRACE_HEADERS = trace-root.h $(trace-events-subdirs:%=%/trace.h)
73
+TRACE_SOURCES = trace-root.c $(trace-events-subdirs:%=%/trace.c)
74
+TRACE_DTRACE =
75
+ifdef CONFIG_TRACE_DTRACE
76
+TRACE_HEADERS += trace-dtrace-root.h $(trace-events-subdirs:%=%/trace-dtrace.h)
77
+TRACE_DTRACE += trace-dtrace-root.dtrace $(trace-events-subdirs:%=%/trace-dtrace.dtrace)
78
+endif
79
+ifdef CONFIG_TRACE_UST
80
+TRACE_HEADERS += trace-ust-root.h $(trace-events-subdirs:%=%/trace-ust.h)
81
+endif
82
+
83
+GENERATED_HEADERS += $(TRACE_HEADERS)
84
+GENERATED_SOURCES += $(TRACE_SOURCES)
85
+
86
+trace-group-name = $(shell dirname $1 | sed -e 's/[^a-zA-Z0-9]/_/g')
87
+
88
+%/trace.h: %/trace.h-timestamp
89
+	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
90
+%/trace.h-timestamp: $(SRC_PATH)/%/trace-events $(tracetool-y)
91
+	$(call quiet-command,$(TRACETOOL) \
92
+		--group=$(call trace-group-name,$@) \
93
+		--format=h \
94
+		--backends=$(TRACE_BACKENDS) \
95
+		$< > $@,"GEN","$(@:%-timestamp=%)")
96
+
97
+%/trace.c: %/trace.c-timestamp
98
+	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
99
+%/trace.c-timestamp: $(SRC_PATH)/%/trace-events $(tracetool-y)
100
+	$(call quiet-command,$(TRACETOOL) \
101
+		--group=$(call trace-group-name,$@) \
102
+		--format=c \
103
+		--backends=$(TRACE_BACKENDS) \
104
+		$< > $@,"GEN","$(@:%-timestamp=%)")
105
+
106
+%/trace-ust.h: %/trace-ust.h-timestamp
107
+	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
108
+%/trace-ust.h-timestamp: $(SRC_PATH)/%/trace-events $(tracetool-y)
109
+	$(call quiet-command,$(TRACETOOL) \
110
+		--group=$(call trace-group-name,$@) \
111
+		--format=ust-events-h \
112
+		--backends=$(TRACE_BACKENDS) \
113
+		$< > $@,"GEN","$(@:%-timestamp=%)")
114
+
115
+%/trace-dtrace.dtrace: %/trace-dtrace.dtrace-timestamp
116
+	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
117
+%/trace-dtrace.dtrace-timestamp: $(SRC_PATH)/%/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y)
118
+	$(call quiet-command,$(TRACETOOL) \
119
+		--group=$(call trace-group-name,$@) \
120
+		--format=d \
121
+		--backends=$(TRACE_BACKENDS) \
122
+		$< > $@,"GEN","$(@:%-timestamp=%)")
123
+
124
+%/trace-dtrace.h: %/trace-dtrace.dtrace $(tracetool-y)
125
+	$(call quiet-command,dtrace -o $@ -h -s $<, "GEN","$@")
126
+
127
+%/trace-dtrace.o: %/trace-dtrace.dtrace $(tracetool-y)
128
+
129
+
130
+trace-root.h: trace-root.h-timestamp
131
+	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
132
+trace-root.h-timestamp: $(SRC_PATH)/trace-events $(tracetool-y)
133
+	$(call quiet-command,$(TRACETOOL) \
134
+		--group=root \
135
+		--format=h \
136
+		--backends=$(TRACE_BACKENDS) \
137
+		$< > $@,"GEN","$(@:%-timestamp=%)")
138
+
139
+trace-root.c: trace-root.c-timestamp
140
+	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
141
+trace-root.c-timestamp: $(SRC_PATH)/trace-events $(tracetool-y)
142
+	$(call quiet-command,$(TRACETOOL) \
143
+		--group=root \
144
+		--format=c \
145
+		--backends=$(TRACE_BACKENDS) \
146
+		$< > $@,"GEN","$(@:%-timestamp=%)")
147
+
148
+trace-ust-root.h: trace-ust-root.h-timestamp
149
+	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
150
+trace-ust-root.h-timestamp: $(SRC_PATH)/trace-events $(tracetool-y)
151
+	$(call quiet-command,$(TRACETOOL) \
152
+		--group=root \
153
+		--format=ust-events-h \
154
+		--backends=$(TRACE_BACKENDS) \
155
+		$< > $@,"GEN","$(@:%-timestamp=%)")
156
+
157
+trace-ust-all.h: trace-ust-all.h-timestamp
158
+	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
159
+trace-ust-all.h-timestamp: $(trace-events-files) $(tracetool-y)
160
+	$(call quiet-command,$(TRACETOOL) \
161
+		--group=all \
162
+		--format=ust-events-h \
163
+		--backends=$(TRACE_BACKENDS) \
164
+		$(trace-events-files) > $@,"GEN","$(@:%-timestamp=%)")
165
+
166
+trace-ust-all.c: trace-ust-all.c-timestamp
167
+	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
168
+trace-ust-all.c-timestamp: $(trace-events-files) $(tracetool-y)
169
+	$(call quiet-command,$(TRACETOOL) \
170
+		--group=all \
171
+		--format=ust-events-c \
172
+		--backends=$(TRACE_BACKENDS) \
173
+		$(trace-events-files) > $@,"GEN","$(@:%-timestamp=%)")
174
+
175
+trace-dtrace-root.dtrace: trace-dtrace-root.dtrace-timestamp
176
+	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
177
+trace-dtrace-root.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y)
178
+	$(call quiet-command,$(TRACETOOL) \
179
+		--group=root \
180
+		--format=d \
181
+		--backends=$(TRACE_BACKENDS) \
182
+		$< > $@,"GEN","$(@:%-timestamp=%)")
183
+
184
+trace-dtrace-root.h: trace-dtrace-root.dtrace
185
+	$(call quiet-command,dtrace -o $@ -h -s $<, "GEN","$@")
186
+
187
+trace-dtrace-root.o: trace-dtrace-root.dtrace
188
+
78 189
 # Don't try to regenerate Makefile or configure
79 190
 # We don't generate any of them
80 191
 Makefile: ;
@@ -160,7 +271,8 @@ dummy := $(call unnest-vars,, \
160 271
                 qom-obj-y \
161 272
                 io-obj-y \
162 273
                 common-obj-y \
163
-                common-obj-m)
274
+                common-obj-m \
275
+                trace-obj-y)
164 276
 
165 277
 ifneq ($(wildcard config-host.mak),)
166 278
 include $(SRC_PATH)/tests/Makefile.include
@@ -223,7 +335,7 @@ subdir-dtc:dtc/libfdt dtc/tests
223 335
 dtc/%:
224 336
 	mkdir -p $@
225 337
 
226
-$(SUBDIR_RULES): libqemuutil.a libqemustub.a $(common-obj-y) $(qom-obj-y) $(crypto-aes-obj-$(CONFIG_USER_ONLY))
338
+$(SUBDIR_RULES): libqemuutil.a libqemustub.a $(common-obj-y) $(qom-obj-y) $(crypto-aes-obj-$(CONFIG_USER_ONLY)) $(trace-obj-y)
227 339
 
228 340
 ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS))
229 341
 # Only keep -O and -g cflags
@@ -247,15 +359,17 @@ libqemuutil.a: $(util-obj-y)
247 359
 
248 360
 ######################################################################
249 361
 
362
+COMMON_LDADDS = $(trace-obj-y) libqemuutil.a libqemustub.a
363
+
250 364
 qemu-img.o: qemu-img-cmds.h
251 365
 
252
-qemu-img$(EXESUF): qemu-img.o $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) libqemuutil.a libqemustub.a
253
-qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) libqemuutil.a libqemustub.a
254
-qemu-io$(EXESUF): qemu-io.o $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) libqemuutil.a libqemustub.a
366
+qemu-img$(EXESUF): qemu-img.o $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
367
+qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
368
+qemu-io$(EXESUF): qemu-io.o $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
255 369
 
256
-qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o libqemuutil.a libqemustub.a
370
+qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o $(COMMON_LDADDS)
257 371
 
258
-fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/9p-marshal.o fsdev/9p-iov-marshal.o libqemuutil.a libqemustub.a
372
+fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/9p-marshal.o fsdev/9p-iov-marshal.o $(COMMON_LDADDS)
259 373
 fsdev/virtfs-proxy-helper$(EXESUF): LIBS += -lcap
260 374
 
261 375
 qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx $(SRC_PATH)/scripts/hxtool
@@ -320,7 +434,7 @@ $(qapi-modules) $(SRC_PATH)/scripts/qapi-introspect.py $(qapi-py)
320 434
 QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)
321 435
 $(qga-obj-y) qemu-ga.o: $(QGALIB_GEN)
322 436
 
323
-qemu-ga$(EXESUF): $(qga-obj-y) libqemuutil.a libqemustub.a
437
+qemu-ga$(EXESUF): $(qga-obj-y) $(COMMON_LDADDS)
324 438
 	$(call LINK, $^)
325 439
 
326 440
 ifdef QEMU_GA_MSI_ENABLED
@@ -345,9 +459,9 @@ ifneq ($(EXESUF),)
345 459
 qemu-ga: qemu-ga$(EXESUF) $(QGA_VSS_PROVIDER) $(QEMU_GA_MSI)
346 460
 endif
347 461
 
348
-ivshmem-client$(EXESUF): $(ivshmem-client-obj-y) libqemuutil.a libqemustub.a
462
+ivshmem-client$(EXESUF): $(ivshmem-client-obj-y) $(COMMON_LDADDS)
349 463
 	$(call LINK, $^)
350
-ivshmem-server$(EXESUF): $(ivshmem-server-obj-y) libqemuutil.a libqemustub.a
464
+ivshmem-server$(EXESUF): $(ivshmem-server-obj-y) $(COMMON_LDADDS)
351 465
 	$(call LINK, $^)
352 466
 
353 467
 module_block.h: $(SRC_PATH)/scripts/modules/module_block.py config-host.mak
@@ -664,6 +778,10 @@ ifneq ($(filter-out $(UNCHECKED_GOALS),$(MAKECMDGOALS)),$(if $(MAKECMDGOALS),,fa
664 778
 Makefile: $(GENERATED_HEADERS)
665 779
 endif
666 780
 
781
+.SECONDARY: $(TRACE_HEADERS) $(TRACE_HEADERS:%=%-timestamp) \
782
+	$(TRACE_SOURCES) $(TRACE_SOURCES:%=%-timestamp) \
783
+	$(TRACE_DTRACE) $(TRACE_DTRACE:%=%-timestamp)
784
+
667 785
 # Include automatically generated dependency files
668 786
 # Dependencies in Makefile.objs files come from our recursive subdir rules
669 787
 -include $(wildcard *.d tests/*.d)

+ 55
- 47
Makefile.objs View File

@@ -118,50 +118,58 @@ ivshmem-server-obj-y = contrib/ivshmem-server/
118 118
 libvhost-user-obj-y = contrib/libvhost-user/
119 119
 
120 120
 ######################################################################
121
-trace-events-y = trace-events
122
-trace-events-y += util/trace-events
123
-trace-events-y += crypto/trace-events
124
-trace-events-y += io/trace-events
125
-trace-events-y += migration/trace-events
126
-trace-events-y += block/trace-events
127
-trace-events-y += hw/block/trace-events
128
-trace-events-y += hw/block/dataplane/trace-events
129
-trace-events-y += hw/char/trace-events
130
-trace-events-y += hw/intc/trace-events
131
-trace-events-y += hw/net/trace-events
132
-trace-events-y += hw/virtio/trace-events
133
-trace-events-y += hw/audio/trace-events
134
-trace-events-y += hw/misc/trace-events
135
-trace-events-y += hw/usb/trace-events
136
-trace-events-y += hw/scsi/trace-events
137
-trace-events-y += hw/nvram/trace-events
138
-trace-events-y += hw/display/trace-events
139
-trace-events-y += hw/input/trace-events
140
-trace-events-y += hw/timer/trace-events
141
-trace-events-y += hw/dma/trace-events
142
-trace-events-y += hw/sparc/trace-events
143
-trace-events-y += hw/sd/trace-events
144
-trace-events-y += hw/isa/trace-events
145
-trace-events-y += hw/mem/trace-events
146
-trace-events-y += hw/i386/trace-events
147
-trace-events-y += hw/i386/xen/trace-events
148
-trace-events-y += hw/9pfs/trace-events
149
-trace-events-y += hw/ppc/trace-events
150
-trace-events-y += hw/pci/trace-events
151
-trace-events-y += hw/s390x/trace-events
152
-trace-events-y += hw/vfio/trace-events
153
-trace-events-y += hw/acpi/trace-events
154
-trace-events-y += hw/arm/trace-events
155
-trace-events-y += hw/alpha/trace-events
156
-trace-events-y += hw/xen/trace-events
157
-trace-events-y += ui/trace-events
158
-trace-events-y += audio/trace-events
159
-trace-events-y += net/trace-events
160
-trace-events-y += target/arm/trace-events
161
-trace-events-y += target/i386/trace-events
162
-trace-events-y += target/sparc/trace-events
163
-trace-events-y += target/s390x/trace-events
164
-trace-events-y += target/ppc/trace-events
165
-trace-events-y += qom/trace-events
166
-trace-events-y += linux-user/trace-events
167
-trace-events-y += qapi/trace-events
121
+trace-events-subdirs =
122
+trace-events-subdirs += util
123
+trace-events-subdirs += crypto
124
+trace-events-subdirs += io
125
+trace-events-subdirs += migration
126
+trace-events-subdirs += block
127
+trace-events-subdirs += hw/block
128
+trace-events-subdirs += hw/block/dataplane
129
+trace-events-subdirs += hw/char
130
+trace-events-subdirs += hw/intc
131
+trace-events-subdirs += hw/net
132
+trace-events-subdirs += hw/virtio
133
+trace-events-subdirs += hw/audio
134
+trace-events-subdirs += hw/misc
135
+trace-events-subdirs += hw/usb
136
+trace-events-subdirs += hw/scsi
137
+trace-events-subdirs += hw/nvram
138
+trace-events-subdirs += hw/display
139
+trace-events-subdirs += hw/input
140
+trace-events-subdirs += hw/timer
141
+trace-events-subdirs += hw/dma
142
+trace-events-subdirs += hw/sparc
143
+trace-events-subdirs += hw/sd
144
+trace-events-subdirs += hw/isa
145
+trace-events-subdirs += hw/mem
146
+trace-events-subdirs += hw/i386
147
+trace-events-subdirs += hw/i386/xen
148
+trace-events-subdirs += hw/9pfs
149
+trace-events-subdirs += hw/ppc
150
+trace-events-subdirs += hw/pci
151
+trace-events-subdirs += hw/s390x
152
+trace-events-subdirs += hw/vfio
153
+trace-events-subdirs += hw/acpi
154
+trace-events-subdirs += hw/arm
155
+trace-events-subdirs += hw/alpha
156
+trace-events-subdirs += hw/xen
157
+trace-events-subdirs += ui
158
+trace-events-subdirs += audio
159
+trace-events-subdirs += net
160
+trace-events-subdirs += target/arm
161
+trace-events-subdirs += target/i386
162
+trace-events-subdirs += target/sparc
163
+trace-events-subdirs += target/s390x
164
+trace-events-subdirs += target/ppc
165
+trace-events-subdirs += qom
166
+trace-events-subdirs += linux-user
167
+trace-events-subdirs += qapi
168
+
169
+trace-events-files = $(SRC_PATH)/trace-events $(trace-events-subdirs:%=$(SRC_PATH)/%/trace-events)
170
+
171
+trace-obj-y = trace-root.o
172
+trace-obj-y += $(trace-events-subdirs:%=%/trace.o)
173
+trace-obj-$(CONFIG_TRACE_UST) += trace-ust-all.o
174
+trace-obj-$(CONFIG_TRACE_DTRACE) += trace-dtrace-root.o
175
+trace-obj-$(CONFIG_TRACE_DTRACE) += $(trace-events-subdirs:%=%/trace-dtrace.o)

+ 5
- 2
Makefile.target View File

@@ -186,7 +186,8 @@ dummy := $(call unnest-vars,.., \
186 186
                qom-obj-y \
187 187
                io-obj-y \
188 188
                common-obj-y \
189
-               common-obj-m)
189
+               common-obj-m \
190
+               trace-obj-y)
190 191
 target-obj-y := $(target-obj-y-save)
191 192
 all-obj-y += $(common-obj-y)
192 193
 all-obj-y += $(target-obj-y)
@@ -198,8 +199,10 @@ all-obj-$(CONFIG_SOFTMMU) += $(io-obj-y)
198 199
 
199 200
 $(QEMU_PROG_BUILD): config-devices.mak
200 201
 
202
+COMMON_LDADDS = $(trace-obj-y) ../libqemuutil.a ../libqemustub.a
203
+
201 204
 # build either PROG or PROGW
202
-$(QEMU_PROG_BUILD): $(all-obj-y) ../libqemuutil.a ../libqemustub.a
205
+$(QEMU_PROG_BUILD): $(all-obj-y) $(COMMON_LDADDS)
203 206
 	$(call LINK, $(filter-out %.mak, $^))
204 207
 ifdef CONFIG_DARWIN
205 208
 	$(call quiet-command,Rez -append $(SRC_PATH)/pc-bios/qemu.rsrc -o $@,"REZ","$(TARGET_DIR)$@")

+ 1
- 1
aio-posix.c View File

@@ -19,7 +19,7 @@
19 19
 #include "qemu/rcu_queue.h"
20 20
 #include "qemu/sockets.h"
21 21
 #include "qemu/cutils.h"
22
-#include "trace.h"
22
+#include "trace-root.h"
23 23
 #ifdef CONFIG_EPOLL_CREATE1
24 24
 #include <sys/epoll.h>
25 25
 #endif

+ 1
- 1
balloon.c View File

@@ -29,7 +29,7 @@
29 29
 #include "exec/cpu-common.h"
30 30
 #include "sysemu/kvm.h"
31 31
 #include "sysemu/balloon.h"
32
-#include "trace.h"
32
+#include "trace-root.h"
33 33
 #include "qmp-commands.h"
34 34
 #include "qapi/qmp/qerror.h"
35 35
 #include "qapi/qmp/qjson.h"

+ 1
- 1
block.c View File

@@ -22,7 +22,7 @@
22 22
  * THE SOFTWARE.
23 23
  */
24 24
 #include "qemu/osdep.h"
25
-#include "trace.h"
25
+#include "block/trace.h"
26 26
 #include "block/block_int.h"
27 27
 #include "block/blockjob.h"
28 28
 #include "block/nbd.h"

+ 0
- 1
blockdev-nbd.c View File

@@ -16,7 +16,6 @@
16 16
 #include "qapi/qmp/qerror.h"
17 17
 #include "sysemu/sysemu.h"
18 18
 #include "qmp-commands.h"
19
-#include "trace.h"
20 19
 #include "block/nbd.h"
21 20
 #include "io/channel-socket.h"
22 21
 

+ 1
- 1
blockdev.c View File

@@ -48,7 +48,7 @@
48 48
 #include "sysemu/sysemu.h"
49 49
 #include "block/block_int.h"
50 50
 #include "qmp-commands.h"
51
-#include "trace.h"
51
+#include "block/trace.h"
52 52
 #include "sysemu/arch_init.h"
53 53
 #include "qemu/cutils.h"
54 54
 #include "qemu/help_option.h"

+ 0
- 1
blockjob.c View File

@@ -25,7 +25,6 @@
25 25
 
26 26
 #include "qemu/osdep.h"
27 27
 #include "qemu-common.h"
28
-#include "trace.h"
29 28
 #include "block/block.h"
30 29
 #include "block/blockjob_int.h"
31 30
 #include "block/block_int.h"

+ 1
- 1
cpu-exec.c View File

@@ -18,7 +18,7 @@
18 18
  */
19 19
 #include "qemu/osdep.h"
20 20
 #include "cpu.h"
21
-#include "trace.h"
21
+#include "trace-root.h"
22 22
 #include "disas/disas.h"
23 23
 #include "exec/exec-all.h"
24 24
 #include "tcg.h"

+ 1
- 1
dma-helpers.c View File

@@ -10,7 +10,7 @@
10 10
 #include "qemu/osdep.h"
11 11
 #include "sysemu/block-backend.h"
12 12
 #include "sysemu/dma.h"
13
-#include "trace.h"
13
+#include "trace-root.h"
14 14
 #include "qemu/thread.h"
15 15
 #include "qemu/main-loop.h"
16 16
 

+ 1
- 1
exec.c View File

@@ -44,7 +44,7 @@
44 44
 #include "sysemu/dma.h"
45 45
 #include "exec/address-spaces.h"
46 46
 #include "sysemu/xen-mapcache.h"
47
-#include "trace.h"
47
+#include "trace-root.h"
48 48
 #endif
49 49
 #include "exec/cpu-all.h"
50 50
 #include "qemu/rcu_queue.h"

+ 0
- 1
hw/net/fsl_etsec/etsec.c View File

@@ -29,7 +29,6 @@
29 29
 #include "qemu/osdep.h"
30 30
 #include "sysemu/sysemu.h"
31 31
 #include "hw/sysbus.h"
32
-#include "trace.h"
33 32
 #include "hw/ptimer.h"
34 33
 #include "etsec.h"
35 34
 #include "registers.h"

+ 1
- 1
include/exec/cpu_ldst_template.h View File

@@ -25,7 +25,7 @@
25 25
  */
26 26
 
27 27
 #if !defined(SOFTMMU_CODE_ACCESS)
28
-#include "trace.h"
28
+#include "trace-root.h"
29 29
 #endif
30 30
 
31 31
 #include "trace/mem.h"

+ 1
- 1
include/exec/cpu_ldst_useronly_template.h View File

@@ -24,7 +24,7 @@
24 24
  */
25 25
 
26 26
 #if !defined(CODE_ACCESS)
27
-#include "trace.h"
27
+#include "trace-root.h"
28 28
 #endif
29 29
 
30 30
 #include "trace/mem.h"

+ 1
- 1
include/hw/xen/xen_common.h View File

@@ -18,7 +18,7 @@
18 18
 #include "hw/xen/xen.h"
19 19
 #include "hw/pci/pci.h"
20 20
 #include "qemu/queue.h"
21
-#include "trace.h"
21
+#include "hw/xen/trace.h"
22 22
 
23 23
 /*
24 24
  * We don't support Xen prior to 4.2.0.

+ 0
- 6
include/trace.h View File

@@ -1,6 +0,0 @@
1
-#ifndef TRACE_H
2
-#define TRACE_H
3
-
4
-#include "trace/generated-tracers.h"
5
-
6
-#endif /* TRACE_H */

+ 1
- 1
ioport.c View File

@@ -29,7 +29,7 @@
29 29
 #include "qemu-common.h"
30 30
 #include "cpu.h"
31 31
 #include "exec/ioport.h"
32
-#include "trace.h"
32
+#include "trace-root.h"
33 33
 #include "exec/memory.h"
34 34
 #include "exec/address-spaces.h"
35 35
 

+ 1
- 1
kvm-all.c View File

@@ -34,7 +34,7 @@
34 34
 #include "exec/ram_addr.h"
35 35
 #include "exec/address-spaces.h"
36 36
 #include "qemu/event_notifier.h"
37
-#include "trace.h"
37
+#include "trace-root.h"
38 38
 #include "hw/irq.h"
39 39
 
40 40
 #include "hw/boards.h"

+ 1
- 1
memory.c View File

@@ -24,7 +24,7 @@
24 24
 #include "qemu/bitops.h"
25 25
 #include "qemu/error-report.h"
26 26
 #include "qom/object.h"
27
-#include "trace.h"
27
+#include "trace-root.h"
28 28
 
29 29
 #include "exec/memory-internal.h"
30 30
 #include "exec/ram_addr.h"

+ 1
- 1
monitor.c View File

@@ -59,7 +59,7 @@
59 59
 #include "qapi/qmp/json-streamer.h"
60 60
 #include "qapi/qmp/json-parser.h"
61 61
 #include "qom/object_interfaces.h"
62
-#include "trace.h"
62
+#include "trace-root.h"
63 63
 #include "trace/control.h"
64 64
 #include "monitor/hmp-target.h"
65 65
 #ifdef CONFIG_TRACE_SIMPLE

+ 1
- 1
qom/cpu.c View File

@@ -29,7 +29,7 @@
29 29
 #include "qemu/error-report.h"
30 30
 #include "sysemu/sysemu.h"
31 31
 #include "hw/qdev-properties.h"
32
-#include "trace.h"
32
+#include "trace-root.h"
33 33
 
34 34
 bool cpu_exists(int64_t id)
35 35
 {

+ 5
- 3
scripts/tracetool.py View File

@@ -137,10 +137,12 @@ def main(args):
137 137
         if probe_prefix is None:
138 138
             probe_prefix = ".".join(["qemu", target_type, target_name])
139 139
 
140
-    if len(args) != 1:
140
+    if len(args) < 1:
141 141
         error_opt("missing trace-events filepath")
142
-    with open(args[0], "r") as fh:
143
-        events = tracetool.read_events(fh)
142
+    events = []
143
+    for arg in args:
144
+        with open(arg, "r") as fh:
145
+            events.extend(tracetool.read_events(fh))
144 146
 
145 147
     try:
146 148
         tracetool.generate(events, arg_group, arg_format, arg_backends,

+ 6
- 1
scripts/tracetool/backend/dtrace.py View File

@@ -36,7 +36,12 @@ def binary():
36 36
 
37 37
 
38 38
 def generate_h_begin(events, group):
39
-    out('#include "trace/generated-tracers-dtrace.h"',
39
+    if group == "root":
40
+        header = "trace-dtrace-root.h"
41
+    else:
42
+        header = "trace-dtrace.h"
43
+
44
+    out('#include "%s"' % header,
40 45
         '')
41 46
 
42 47
 

+ 0
- 1
scripts/tracetool/backend/simple.py View File

@@ -44,7 +44,6 @@ def generate_h(event, group):
44 44
 
45 45
 def generate_c_begin(events, group):
46 46
     out('#include "qemu/osdep.h"',
47
-        '#include "trace.h"',
48 47
         '#include "trace/control.h"',
49 48
         '#include "trace/simple.h"',
50 49
         '')

+ 6
- 1
scripts/tracetool/backend/ust.py View File

@@ -20,8 +20,13 @@ PUBLIC = True
20 20
 
21 21
 
22 22
 def generate_h_begin(events, group):
23
+    if group == "root":
24
+        header = "trace-ust-root.h"
25
+    else:
26
+        header = "trace-ust.h"
27
+
23 28
     out('#include <lttng/tracepoint.h>',
24
-        '#include "trace/generated-ust-provider.h"',
29
+        '#include "%s"' % header,
25 30
         '')
26 31
 
27 32
 

+ 6
- 1
scripts/tracetool/format/c.py View File

@@ -20,10 +20,15 @@ def generate(events, backend, group):
20 20
     active_events = [e for e in events
21 21
                      if "disable" not in e.properties]
22 22
 
23
+    if group == "root":
24
+        header = "trace-root.h"
25
+    else:
26
+        header = "trace.h"
27
+
23 28
     out('/* This file is autogenerated by tracetool, do not edit. */',
24 29
         '',
25 30
         '#include "qemu/osdep.h"',
26
-        '#include "trace.h"',
31
+        '#include "%s"' % header,
27 32
         '')
28 33
 
29 34
     for e in events:

+ 5
- 1
scripts/tracetool/format/tcg_h.py View File

@@ -28,13 +28,17 @@ def vcpu_transform_args(args):
28 28
 
29 29
 
30 30
 def generate(events, backend, group):
31
+    if group == "root":
32
+        header = "trace-root.h"
33
+    else:
34
+        header = "trace.h"
35
+
31 36
     out('/* This file is autogenerated by tracetool, do not edit. */',
32 37
         '/* You must include this file after the inclusion of helper.h */',
33 38
         '',
34 39
         '#ifndef TRACE_%s_GENERATED_TCG_TRACERS_H' % group.upper(),
35 40
         '#define TRACE_%s_GENERATED_TCG_TRACERS_H' % group.upper(),
36 41
         '',
37
-        '#include "trace.h"',
38 42
         '#include "exec/helper-proto.h"',
39 43
         '',
40 44
         )

+ 5
- 1
scripts/tracetool/format/tcg_helper_c.py View File

@@ -41,6 +41,11 @@ def vcpu_transform_args(args, mode):
41 41
 
42 42
 
43 43
 def generate(events, backend, group):
44
+    if group == "root":
45
+        header = "trace-root.h"
46
+    else:
47
+        header = "trace.h"
48
+
44 49
     events = [e for e in events
45 50
               if "disable" not in e.properties]
46 51
 
@@ -49,7 +54,6 @@ def generate(events, backend, group):
49 54
         '#include "qemu/osdep.h"',
50 55
         '#include "qemu-common.h"',
51 56
         '#include "cpu.h"',
52
-        '#include "trace.h"',
53 57
         '#include "exec/helper-proto.h"',
54 58
         '',
55 59
         )

+ 1
- 1
scripts/tracetool/format/ust_events_c.py View File

@@ -32,4 +32,4 @@ def generate(events, backend, group):
32 32
         ' */',
33 33
         '#pragma GCC diagnostic ignored "-Wredundant-decls"',
34 34
         '',
35
-        '#include "generated-ust-provider.h"')
35
+        '#include "trace-ust-all.h"')

+ 6
- 1
scripts/tracetool/format/ust_events_h.py View File

@@ -20,13 +20,18 @@ def generate(events, backend, group):
20 20
     events = [e for e in events
21 21
               if "disabled" not in e.properties]
22 22
 
23
+    if group == "all":
24
+        include = "trace-ust-all.h"
25
+    else:
26
+        include = "trace-ust.h"
27
+
23 28
     out('/* This file is autogenerated by tracetool, do not edit. */',
24 29
         '',
25 30
         '#undef TRACEPOINT_PROVIDER',
26 31
         '#define TRACEPOINT_PROVIDER qemu',
27 32
         '',
28 33
         '#undef TRACEPOINT_INCLUDE_FILE',
29
-        '#define TRACEPOINT_INCLUDE_FILE ./generated-ust-provider.h',
34
+        '#define TRACEPOINT_INCLUDE_FILE ./%s' % include,
30 35
         '',
31 36
         '#if !defined (TRACE_%s_GENERATED_UST_H) || \\'  % group.upper(),
32 37
         '     defined(TRACEPOINT_HEADER_MULTI_READ)',

+ 1
- 1
spice-qemu-char.c View File

@@ -1,5 +1,5 @@
1 1
 #include "qemu/osdep.h"
2
-#include "trace.h"
2
+#include "trace-root.h"
3 3
 #include "ui/qemu-spice.h"
4 4
 #include "sysemu/char.h"
5 5
 #include "qemu/error-report.h"

+ 1
- 1
tests/Makefile.include View File

@@ -491,7 +491,7 @@ QEMU_CFLAGS += -I$(SRC_PATH)/tests
491 491
 
492 492
 
493 493
 # Deps that are common to various different sets of tests below
494
-test-util-obj-y = libqemuutil.a libqemustub.a
494
+test-util-obj-y = $(trace-obj-y) libqemuutil.a libqemustub.a
495 495
 test-qom-obj-y = $(qom-obj-y) $(test-util-obj-y)
496 496
 test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o \
497 497
 	tests/test-qapi-event.o tests/test-qmp-introspect.o \

+ 1
- 1
thread-pool.c View File

@@ -19,7 +19,7 @@
19 19
 #include "qemu/queue.h"
20 20
 #include "qemu/thread.h"
21 21
 #include "qemu/coroutine.h"
22
-#include "trace.h"
22
+#include "trace-root.h"
23 23
 #include "block/thread-pool.h"
24 24
 #include "qemu/main-loop.h"
25 25
 

+ 5
- 89
trace/Makefile.objs View File

@@ -8,98 +8,16 @@
8 8
 tracetool-y = $(SRC_PATH)/scripts/tracetool.py
9 9
 tracetool-y += $(shell find $(SRC_PATH)/scripts/tracetool -name "*.py")
10 10
 
11
-$(BUILD_DIR)/trace-events-all: $(trace-events-y:%=$(SRC_PATH)/%)
11
+$(BUILD_DIR)/trace-events-all: $(trace-events-files)
12 12
 	$(call quiet-command,cat $^ > $@)
13 13
 
14
-######################################################################
15
-# Auto-generated event descriptions for LTTng ust code
16
-
17
-ifeq ($(findstring ust,$(TRACE_BACKENDS)),ust)
18
-
19
-$(obj)/generated-ust-provider.h: $(obj)/generated-ust-provider.h-timestamp
20
-	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
21
-$(obj)/generated-ust-provider.h-timestamp: $(BUILD_DIR)/trace-events-all $(tracetool-y)
22
-	$(call quiet-command,$(TRACETOOL) \
23
-		--group=all \
24
-		--format=ust-events-h \
25
-		--backends=$(TRACE_BACKENDS) \
26
-		$< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
27
-
28
-$(obj)/generated-ust.c: $(obj)/generated-ust.c-timestamp $(BUILD_DIR)/config-host.mak
29
-	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
30
-$(obj)/generated-ust.c-timestamp: $(BUILD_DIR)/trace-events-all $(tracetool-y)
31
-	$(call quiet-command,$(TRACETOOL) \
32
-		--group=all \
33
-		--format=ust-events-c \
34
-		--backends=$(TRACE_BACKENDS) \
35
-		$< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
36
-
37
-$(obj)/generated-tracers.h: $(obj)/generated-ust-provider.h
38
-$(obj)/generated-tracers.c: $(obj)/generated-ust.c
39
-
40
-endif
41
-
42
-
43
-######################################################################
44
-# Auto-generated tracing routines
45
-
46
-##################################################
47
-# Execution level
48
-
49
-$(obj)/generated-tracers.h: $(obj)/generated-tracers.h-timestamp
50
-	@cmp -s $< $@ || cp $< $@
51
-$(obj)/generated-tracers.h-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)/config-host.mak $(tracetool-y)
52
-	$(call quiet-command,$(TRACETOOL) \
53
-		--group=all \
54
-		--format=h \
55
-		--backends=$(TRACE_BACKENDS) \
56
-		$< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
57
-
58
-##############################
59
-# non-DTrace
60
-
61
-$(obj)/generated-tracers.c: $(obj)/generated-tracers.c-timestamp
62
-	@cmp -s $< $@ || cp $< $@
63
-$(obj)/generated-tracers.c-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)/config-host.mak $(tracetool-y)
64
-	$(call quiet-command,$(TRACETOOL) \
65
-		--group=all \
66
-		--format=c \
67
-		--backends=$(TRACE_BACKENDS) \
68
-		$< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
69
-
70
-$(obj)/generated-tracers.o: $(obj)/generated-tracers.c $(obj)/generated-tracers.h
71
-
72
-##############################
73
-# DTrace
74
-
75
-# Normal practice is to name DTrace probe file with a '.d' extension
76
-# but that gets picked up by QEMU's Makefile as an external dependency
77
-# rule file. So we use '.dtrace' instead
78
-ifeq ($(findstring dtrace,$(TRACE_BACKENDS)),dtrace)
79
-
80
-$(obj)/generated-tracers-dtrace.dtrace: $(obj)/generated-tracers-dtrace.dtrace-timestamp
81
-	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
82
-$(obj)/generated-tracers-dtrace.dtrace-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)/config-host.mak $(tracetool-y)
83
-	$(call quiet-command,$(TRACETOOL) \
84
-		--group=all \
85
-		--format=d \
86
-		--backends=$(TRACE_BACKENDS) \
87
-		$< > $@,"GEN","$(patsubst %-timestamp,%,$@)")
88
-
89
-$(obj)/generated-tracers-dtrace.h: $(obj)/generated-tracers-dtrace.dtrace
90
-	$(call quiet-command,dtrace -o $@ -h -s $<,"GEN","$@")
91
-
92
-$(obj)/generated-tracers-dtrace.o: $(obj)/generated-tracers-dtrace.dtrace
93
-
94
-util-obj-y += generated-tracers-dtrace.o
95
-endif
96 14
 
97 15
 ##################################################
98 16
 # Translation level
99 17
 
100 18
 $(obj)/generated-helpers-wrappers.h: $(obj)/generated-helpers-wrappers.h-timestamp
101 19
 	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
102
-$(obj)/generated-helpers-wrappers.h-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)/config-host.mak $(tracetool-y)
20
+$(obj)/generated-helpers-wrappers.h-timestamp: $(trace-events-files) $(BUILD_DIR)/config-host.mak $(tracetool-y)
103 21
 	$(call quiet-command,$(TRACETOOL) \
104 22
 		--group=all \
105 23
 		--format=tcg-helper-wrapper-h \
@@ -108,7 +26,7 @@ $(obj)/generated-helpers-wrappers.h-timestamp: $(BUILD_DIR)/trace-events-all $(B
108 26
 
109 27
 $(obj)/generated-helpers.h: $(obj)/generated-helpers.h-timestamp
110 28
 	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
111
-$(obj)/generated-helpers.h-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)/config-host.mak $(tracetool-y)
29
+$(obj)/generated-helpers.h-timestamp: $(trace-events-files) $(BUILD_DIR)/config-host.mak $(tracetool-y)
112 30
 	$(call quiet-command,$(TRACETOOL) \
113 31
 		--group=all \
114 32
 		--format=tcg-helper-h \
@@ -117,7 +35,7 @@ $(obj)/generated-helpers.h-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)
117 35
 
118 36
 $(obj)/generated-helpers.c: $(obj)/generated-helpers.c-timestamp
119 37
 	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
120
-$(obj)/generated-helpers.c-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)/config-host.mak $(tracetool-y)
38
+$(obj)/generated-helpers.c-timestamp: $(trace-events-files) $(BUILD_DIR)/config-host.mak $(tracetool-y)
121 39
 	$(call quiet-command,$(TRACETOOL) \
122 40
 		--group=all \
123 41
 		--format=tcg-helper-c \
@@ -131,7 +49,7 @@ target-obj-y += generated-helpers.o
131 49
 
132 50
 $(obj)/generated-tcg-tracers.h: $(obj)/generated-tcg-tracers.h-timestamp
133 51
 	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
134
-$(obj)/generated-tcg-tracers.h-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)/config-host.mak $(tracetool-y)
52
+$(obj)/generated-tcg-tracers.h-timestamp: $(trace-events-files) $(BUILD_DIR)/config-host.mak $(tracetool-y)
135 53
 	$(call quiet-command,$(TRACETOOL) \
136 54
 		--group=all \
137 55
 		--format=tcg-h \
@@ -142,10 +60,8 @@ $(obj)/generated-tcg-tracers.h-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_
142 60
 ######################################################################
143 61
 # Backend code
144 62
 
145
-util-obj-y += generated-tracers.o
146 63
 util-obj-$(CONFIG_TRACE_SIMPLE) += simple.o
147 64
 util-obj-$(CONFIG_TRACE_FTRACE) += ftrace.o
148
-util-obj-$(CONFIG_TRACE_UST) += generated-ust.o
149 65
 util-obj-y += control.o
150 66
 target-obj-y += control-target.o
151 67
 util-obj-y += qmp.o

+ 1
- 1
trace/control-target.c View File

@@ -9,7 +9,7 @@
9 9
 
10 10
 #include "qemu/osdep.h"
11 11
 #include "cpu.h"
12
-#include "trace.h"
12
+#include "trace-root.h"
13 13
 #include "trace/control.h"
14 14
 #include "translate-all.h"
15 15
 

+ 1
- 1
trace/control.c View File

@@ -26,7 +26,7 @@
26 26
 #include "qemu/error-report.h"
27 27
 #include "qemu/config-file.h"
28 28
 #include "monitor/monitor.h"
29
-#include "trace.h"
29
+#include "trace-root.h"
30 30
 
31 31
 int trace_events_enabled_count;
32 32
 

+ 1
- 1
trace/ftrace.c View File

@@ -10,8 +10,8 @@
10 10
  */
11 11
 
12 12
 #include "qemu/osdep.h"
13
-#include "trace.h"
14 13
 #include "trace/control.h"
14
+#include "trace/ftrace.h"
15 15
 
16 16
 int trace_marker_fd;
17 17
 

+ 0
- 1
trace/simple.c View File

@@ -13,7 +13,6 @@
13 13
 #include <pthread.h>
14 14
 #endif
15 15
 #include "qemu/timer.h"
16
-#include "trace.h"
17 16
 #include "trace/control.h"
18 17
 #include "trace/simple.h"
19 18
 

+ 1
- 1
translate-all.c View File

@@ -25,7 +25,7 @@
25 25
 #include "qemu-common.h"
26 26
 #define NO_CPU_IO_DEFS
27 27
 #include "cpu.h"
28
-#include "trace.h"
28
+#include "trace-root.h"
29 29
 #include "disas/disas.h"
30 30
 #include "exec/exec-all.h"
31 31
 #include "tcg.h"

+ 1
- 1
vl.c View File

@@ -110,7 +110,7 @@ int main(int argc, char **argv)
110 110
 
111 111
 #include "slirp/libslirp.h"
112 112
 
113
-#include "trace.h"
113
+#include "trace-root.h"
114 114
 #include "trace/control.h"
115 115
 #include "qemu/queue.h"
116 116
 #include "sysemu/arch_init.h"

+ 1
- 1
xen-hvm.c View File

@@ -22,7 +22,7 @@
22 22
 #include "qemu/error-report.h"
23 23
 #include "qemu/range.h"
24 24
 #include "sysemu/xen-mapcache.h"
25
-#include "trace.h"
25
+#include "trace-root.h"
26 26
 #include "exec/address-spaces.h"
27 27
 
28 28
 #include <xen/hvm/ioreq.h>

+ 1
- 1
xen-mapcache.c View File

@@ -19,7 +19,7 @@
19 19
 #include <xen/hvm/params.h>
20 20
 
21 21
 #include "sysemu/xen-mapcache.h"
22
-#include "trace.h"
22
+#include "trace-root.h"
23 23
 
24 24
 
25 25
 //#define MAPCACHE_DEBUG

Loading…
Cancel
Save