qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

filemon: fix watch IDs to avoid potential wraparound issues

Watch IDs are allocated from incrementing a int counter against
the QFileMonitor object. In very long life QEMU processes with
a huge amount of USB MTP activity creating & deleting directories
it is just about conceivable that the int counter can wrap
around. This would result in incorrect behaviour of the file
monitor watch APIs due to clashing watch IDs.

Instead of trying to detect this situation, this patch changes
the way watch IDs are allocated. It is turned into an int64_t
variable where the high 32 bits are set from the underlying
inotify "int" ID. This gives an ID that is guaranteed unique
for the directory as a whole, and we can rely on the kernel
to enforce this. QFileMonitor then sets the low 32 bits from
a per-directory counter.

The USB MTP device only sets watches on the directory as a
whole, not files within, so there is no risk of guest
triggered wrap around on the low 32 bits.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>

+105 -90
+1 -1
authz/listfile.c
··· 93 93 94 94 95 95 static void 96 - qauthz_list_file_event(int wd G_GNUC_UNUSED, 96 + qauthz_list_file_event(int64_t wd G_GNUC_UNUSED, 97 97 QFileMonitorEvent ev G_GNUC_UNUSED, 98 98 const char *name G_GNUC_UNUSED, 99 99 void *opaque)
+5 -5
hw/usb/dev-mtp.c
··· 170 170 char *path; 171 171 struct stat stat; 172 172 /* file monitor watch id */ 173 - int watchid; 173 + int64_t watchid; 174 174 MTPObject *parent; 175 175 uint32_t nchildren; 176 176 QLIST_HEAD(, MTPObject) children; ··· 498 498 return NULL; 499 499 } 500 500 501 - static MTPObject *usb_mtp_object_lookup_id(MTPState *s, int id) 501 + static MTPObject *usb_mtp_object_lookup_id(MTPState *s, int64_t id) 502 502 { 503 503 MTPObject *iter; 504 504 ··· 511 511 return NULL; 512 512 } 513 513 514 - static void file_monitor_event(int id, 514 + static void file_monitor_event(int64_t id, 515 515 QFileMonitorEvent ev, 516 516 const char *name, 517 517 void *opaque) ··· 625 625 } 626 626 627 627 if (s->file_monitor) { 628 - int id = qemu_file_monitor_add_watch(s->file_monitor, o->path, NULL, 629 - file_monitor_event, s, &err); 628 + int64_t id = qemu_file_monitor_add_watch(s->file_monitor, o->path, NULL, 629 + file_monitor_event, s, &err); 630 630 if (id == -1) { 631 631 error_report("usb-mtp: failed to add watch for %s: %s", o->path, 632 632 error_get_pretty(err));
+1 -1
include/authz/listfile.h
··· 92 92 char *filename; 93 93 bool refresh; 94 94 QFileMonitor *file_monitor; 95 - int file_watch; 95 + int64_t file_watch; 96 96 }; 97 97 98 98
+8 -8
include/qemu/filemonitor.h
··· 52 52 * empty. 53 53 * 54 54 */ 55 - typedef void (*QFileMonitorHandler)(int id, 55 + typedef void (*QFileMonitorHandler)(int64_t id, 56 56 QFileMonitorEvent event, 57 57 const char *filename, 58 58 void *opaque); ··· 103 103 * 104 104 * Returns: a positive integer watch ID, or -1 on error 105 105 */ 106 - int qemu_file_monitor_add_watch(QFileMonitor *mon, 107 - const char *dirpath, 108 - const char *filename, 109 - QFileMonitorHandler cb, 110 - void *opaque, 111 - Error **errp); 106 + int64_t qemu_file_monitor_add_watch(QFileMonitor *mon, 107 + const char *dirpath, 108 + const char *filename, 109 + QFileMonitorHandler cb, 110 + void *opaque, 111 + Error **errp); 112 112 113 113 /** 114 114 * qemu_file_monitor_remove_watch: ··· 123 123 */ 124 124 void qemu_file_monitor_remove_watch(QFileMonitor *mon, 125 125 const char *dirpath, 126 - int id); 126 + int64_t id); 127 127 128 128 #endif /* QEMU_FILE_MONITOR_H */
+72 -58
tests/test-util-filemonitor.c
··· 43 43 int type; 44 44 const char *filesrc; 45 45 const char *filedst; 46 - int watchid; 46 + int64_t *watchid; 47 47 int eventid; 48 48 } QFileMonitorTestOp; 49 49 50 50 typedef struct { 51 - int id; 51 + int64_t id; 52 52 QFileMonitorEvent event; 53 53 char *filename; 54 54 } QFileMonitorTestRecord; ··· 90 90 * an ordered list of all events that it receives 91 91 */ 92 92 static void 93 - qemu_file_monitor_test_handler(int id, 93 + qemu_file_monitor_test_handler(int64_t id, 94 94 QFileMonitorEvent event, 95 95 const char *filename, 96 96 void *opaque) ··· 156 156 */ 157 157 static bool 158 158 qemu_file_monitor_test_expect(QFileMonitorTestData *data, 159 - int id, 159 + int64_t id, 160 160 QFileMonitorEvent event, 161 161 const char *filename) 162 162 { ··· 166 166 rec = qemu_file_monitor_test_next_record(data); 167 167 168 168 if (!rec) { 169 - g_printerr("Missing event watch id %d event %d file %s\n", 169 + g_printerr("Missing event watch id %" PRIx64 " event %d file %s\n", 170 170 id, event, filename); 171 171 return false; 172 172 } 173 173 174 174 if (id != rec->id) { 175 - g_printerr("Expected watch id %d but got %d\n", id, rec->id); 175 + g_printerr("Expected watch id %" PRIx64 " but got %" PRIx64 "\n", 176 + id, rec->id); 176 177 goto cleanup; 177 178 } 178 179 ··· 198 199 static void 199 200 test_file_monitor_events(void) 200 201 { 202 + int64_t watch0 = 0; 203 + int64_t watch1 = 0; 204 + int64_t watch2 = 0; 205 + int64_t watch3 = 0; 206 + int64_t watch4 = 0; 207 + int64_t watch5 = 0; 201 208 QFileMonitorTestOp ops[] = { 202 209 { .type = QFILE_MONITOR_TEST_OP_ADD_WATCH, 203 - .filesrc = NULL, .watchid = 0 }, 210 + .filesrc = NULL, .watchid = &watch0 }, 204 211 { .type = QFILE_MONITOR_TEST_OP_ADD_WATCH, 205 - .filesrc = "one.txt", .watchid = 1 }, 212 + .filesrc = "one.txt", .watchid = &watch1 }, 206 213 { .type = QFILE_MONITOR_TEST_OP_ADD_WATCH, 207 - .filesrc = "two.txt", .watchid = 2 }, 214 + .filesrc = "two.txt", .watchid = &watch2 }, 208 215 209 216 210 217 { .type = QFILE_MONITOR_TEST_OP_CREATE, 211 218 .filesrc = "one.txt", }, 212 219 { .type = QFILE_MONITOR_TEST_OP_EVENT, 213 - .filesrc = "one.txt", .watchid = 0, 220 + .filesrc = "one.txt", .watchid = &watch0, 214 221 .eventid = QFILE_MONITOR_EVENT_CREATED }, 215 222 { .type = QFILE_MONITOR_TEST_OP_EVENT, 216 - .filesrc = "one.txt", .watchid = 1, 223 + .filesrc = "one.txt", .watchid = &watch1, 217 224 .eventid = QFILE_MONITOR_EVENT_CREATED }, 218 225 219 226 220 227 { .type = QFILE_MONITOR_TEST_OP_CREATE, 221 228 .filesrc = "two.txt", }, 222 229 { .type = QFILE_MONITOR_TEST_OP_EVENT, 223 - .filesrc = "two.txt", .watchid = 0, 230 + .filesrc = "two.txt", .watchid = &watch0, 224 231 .eventid = QFILE_MONITOR_EVENT_CREATED }, 225 232 { .type = QFILE_MONITOR_TEST_OP_EVENT, 226 - .filesrc = "two.txt", .watchid = 2, 233 + .filesrc = "two.txt", .watchid = &watch2, 227 234 .eventid = QFILE_MONITOR_EVENT_CREATED }, 228 235 229 236 230 237 { .type = QFILE_MONITOR_TEST_OP_CREATE, 231 238 .filesrc = "three.txt", }, 232 239 { .type = QFILE_MONITOR_TEST_OP_EVENT, 233 - .filesrc = "three.txt", .watchid = 0, 240 + .filesrc = "three.txt", .watchid = &watch0, 234 241 .eventid = QFILE_MONITOR_EVENT_CREATED }, 235 242 236 243 237 244 { .type = QFILE_MONITOR_TEST_OP_UNLINK, 238 245 .filesrc = "three.txt", }, 239 246 { .type = QFILE_MONITOR_TEST_OP_EVENT, 240 - .filesrc = "three.txt", .watchid = 0, 247 + .filesrc = "three.txt", .watchid = &watch0, 241 248 .eventid = QFILE_MONITOR_EVENT_DELETED }, 242 249 243 250 244 251 { .type = QFILE_MONITOR_TEST_OP_RENAME, 245 252 .filesrc = "one.txt", .filedst = "two.txt" }, 246 253 { .type = QFILE_MONITOR_TEST_OP_EVENT, 247 - .filesrc = "one.txt", .watchid = 0, 254 + .filesrc = "one.txt", .watchid = &watch0, 248 255 .eventid = QFILE_MONITOR_EVENT_DELETED }, 249 256 { .type = QFILE_MONITOR_TEST_OP_EVENT, 250 - .filesrc = "one.txt", .watchid = 1, 257 + .filesrc = "one.txt", .watchid = &watch1, 251 258 .eventid = QFILE_MONITOR_EVENT_DELETED }, 252 259 { .type = QFILE_MONITOR_TEST_OP_EVENT, 253 - .filesrc = "two.txt", .watchid = 0, 260 + .filesrc = "two.txt", .watchid = &watch0, 254 261 .eventid = QFILE_MONITOR_EVENT_CREATED }, 255 262 { .type = QFILE_MONITOR_TEST_OP_EVENT, 256 - .filesrc = "two.txt", .watchid = 2, 263 + .filesrc = "two.txt", .watchid = &watch2, 257 264 .eventid = QFILE_MONITOR_EVENT_CREATED }, 258 265 259 266 260 267 { .type = QFILE_MONITOR_TEST_OP_APPEND, 261 268 .filesrc = "two.txt", }, 262 269 { .type = QFILE_MONITOR_TEST_OP_EVENT, 263 - .filesrc = "two.txt", .watchid = 0, 270 + .filesrc = "two.txt", .watchid = &watch0, 264 271 .eventid = QFILE_MONITOR_EVENT_MODIFIED }, 265 272 { .type = QFILE_MONITOR_TEST_OP_EVENT, 266 - .filesrc = "two.txt", .watchid = 2, 273 + .filesrc = "two.txt", .watchid = &watch2, 267 274 .eventid = QFILE_MONITOR_EVENT_MODIFIED }, 268 275 269 276 270 277 { .type = QFILE_MONITOR_TEST_OP_TOUCH, 271 278 .filesrc = "two.txt", }, 272 279 { .type = QFILE_MONITOR_TEST_OP_EVENT, 273 - .filesrc = "two.txt", .watchid = 0, 280 + .filesrc = "two.txt", .watchid = &watch0, 274 281 .eventid = QFILE_MONITOR_EVENT_ATTRIBUTES }, 275 282 { .type = QFILE_MONITOR_TEST_OP_EVENT, 276 - .filesrc = "two.txt", .watchid = 2, 283 + .filesrc = "two.txt", .watchid = &watch2, 277 284 .eventid = QFILE_MONITOR_EVENT_ATTRIBUTES }, 278 285 279 286 280 287 { .type = QFILE_MONITOR_TEST_OP_DEL_WATCH, 281 - .filesrc = "one.txt", .watchid = 1 }, 288 + .filesrc = "one.txt", .watchid = &watch1 }, 282 289 { .type = QFILE_MONITOR_TEST_OP_ADD_WATCH, 283 - .filesrc = "one.txt", .watchid = 3 }, 290 + .filesrc = "one.txt", .watchid = &watch3 }, 284 291 { .type = QFILE_MONITOR_TEST_OP_CREATE, 285 292 .filesrc = "one.txt", }, 286 293 { .type = QFILE_MONITOR_TEST_OP_EVENT, 287 - .filesrc = "one.txt", .watchid = 0, 294 + .filesrc = "one.txt", .watchid = &watch0, 288 295 .eventid = QFILE_MONITOR_EVENT_CREATED }, 289 296 { .type = QFILE_MONITOR_TEST_OP_EVENT, 290 - .filesrc = "one.txt", .watchid = 3, 297 + .filesrc = "one.txt", .watchid = &watch3, 291 298 .eventid = QFILE_MONITOR_EVENT_CREATED }, 292 299 293 300 294 301 { .type = QFILE_MONITOR_TEST_OP_DEL_WATCH, 295 - .filesrc = "one.txt", .watchid = 3 }, 302 + .filesrc = "one.txt", .watchid = &watch3 }, 296 303 { .type = QFILE_MONITOR_TEST_OP_UNLINK, 297 304 .filesrc = "one.txt", }, 298 305 { .type = QFILE_MONITOR_TEST_OP_EVENT, 299 - .filesrc = "one.txt", .watchid = 0, 306 + .filesrc = "one.txt", .watchid = &watch0, 300 307 .eventid = QFILE_MONITOR_EVENT_DELETED }, 301 308 302 309 303 310 { .type = QFILE_MONITOR_TEST_OP_MKDIR, 304 311 .filesrc = "fish", }, 305 312 { .type = QFILE_MONITOR_TEST_OP_EVENT, 306 - .filesrc = "fish", .watchid = 0, 313 + .filesrc = "fish", .watchid = &watch0, 307 314 .eventid = QFILE_MONITOR_EVENT_CREATED }, 308 315 309 316 310 317 { .type = QFILE_MONITOR_TEST_OP_ADD_WATCH, 311 - .filesrc = "fish/", .watchid = 4 }, 318 + .filesrc = "fish/", .watchid = &watch4 }, 312 319 { .type = QFILE_MONITOR_TEST_OP_ADD_WATCH, 313 - .filesrc = "fish/one.txt", .watchid = 5 }, 320 + .filesrc = "fish/one.txt", .watchid = &watch5 }, 314 321 { .type = QFILE_MONITOR_TEST_OP_CREATE, 315 322 .filesrc = "fish/one.txt", }, 316 323 { .type = QFILE_MONITOR_TEST_OP_EVENT, 317 - .filesrc = "one.txt", .watchid = 4, 324 + .filesrc = "one.txt", .watchid = &watch4, 318 325 .eventid = QFILE_MONITOR_EVENT_CREATED }, 319 326 { .type = QFILE_MONITOR_TEST_OP_EVENT, 320 - .filesrc = "one.txt", .watchid = 5, 327 + .filesrc = "one.txt", .watchid = &watch5, 321 328 .eventid = QFILE_MONITOR_EVENT_CREATED }, 322 329 323 330 324 331 { .type = QFILE_MONITOR_TEST_OP_DEL_WATCH, 325 - .filesrc = "fish/one.txt", .watchid = 5 }, 332 + .filesrc = "fish/one.txt", .watchid = &watch5 }, 326 333 { .type = QFILE_MONITOR_TEST_OP_RENAME, 327 334 .filesrc = "fish/one.txt", .filedst = "two.txt", }, 328 335 { .type = QFILE_MONITOR_TEST_OP_EVENT, 329 - .filesrc = "one.txt", .watchid = 4, 336 + .filesrc = "one.txt", .watchid = &watch4, 330 337 .eventid = QFILE_MONITOR_EVENT_DELETED }, 331 338 { .type = QFILE_MONITOR_TEST_OP_EVENT, 332 - .filesrc = "two.txt", .watchid = 0, 339 + .filesrc = "two.txt", .watchid = &watch0, 333 340 .eventid = QFILE_MONITOR_EVENT_CREATED }, 334 341 { .type = QFILE_MONITOR_TEST_OP_EVENT, 335 - .filesrc = "two.txt", .watchid = 2, 342 + .filesrc = "two.txt", .watchid = &watch2, 336 343 .eventid = QFILE_MONITOR_EVENT_CREATED }, 337 344 338 345 339 346 { .type = QFILE_MONITOR_TEST_OP_RMDIR, 340 347 .filesrc = "fish", }, 341 348 { .type = QFILE_MONITOR_TEST_OP_EVENT, 342 - .filesrc = "", .watchid = 4, 349 + .filesrc = "", .watchid = &watch4, 343 350 .eventid = QFILE_MONITOR_EVENT_IGNORED }, 344 351 { .type = QFILE_MONITOR_TEST_OP_EVENT, 345 - .filesrc = "fish", .watchid = 0, 352 + .filesrc = "fish", .watchid = &watch0, 346 353 .eventid = QFILE_MONITOR_EVENT_DELETED }, 347 354 { .type = QFILE_MONITOR_TEST_OP_DEL_WATCH, 348 - .filesrc = "fish", .watchid = 4 }, 355 + .filesrc = "fish", .watchid = &watch4 }, 349 356 350 357 351 358 { .type = QFILE_MONITOR_TEST_OP_UNLINK, 352 359 .filesrc = "two.txt", }, 353 360 { .type = QFILE_MONITOR_TEST_OP_EVENT, 354 - .filesrc = "two.txt", .watchid = 0, 361 + .filesrc = "two.txt", .watchid = &watch0, 355 362 .eventid = QFILE_MONITOR_EVENT_DELETED }, 356 363 { .type = QFILE_MONITOR_TEST_OP_EVENT, 357 - .filesrc = "two.txt", .watchid = 2, 364 + .filesrc = "two.txt", .watchid = &watch2, 358 365 .eventid = QFILE_MONITOR_EVENT_DELETED }, 359 366 360 367 361 368 { .type = QFILE_MONITOR_TEST_OP_DEL_WATCH, 362 - .filesrc = "two.txt", .watchid = 2 }, 369 + .filesrc = "two.txt", .watchid = &watch2 }, 363 370 { .type = QFILE_MONITOR_TEST_OP_DEL_WATCH, 364 - .filesrc = NULL, .watchid = 0 }, 371 + .filesrc = NULL, .watchid = &watch0 }, 365 372 }; 366 373 Error *local_err = NULL; 367 374 GError *gerr = NULL; ··· 374 381 char *pathsrc = NULL; 375 382 char *pathdst = NULL; 376 383 QFileMonitorTestData data; 384 + GHashTable *ids = g_hash_table_new(g_int64_hash, g_int64_equal); 377 385 378 386 qemu_mutex_init(&data.lock); 379 387 data.records = NULL; ··· 414 422 for (i = 0; i < G_N_ELEMENTS(ops); i++) { 415 423 const QFileMonitorTestOp *op = &(ops[i]); 416 424 int fd; 417 - int watchid; 418 425 struct utimbuf ubuf; 419 426 char *watchdir; 420 427 const char *watchfile; ··· 427 434 switch (op->type) { 428 435 case QFILE_MONITOR_TEST_OP_ADD_WATCH: 429 436 if (debug) { 430 - g_printerr("Add watch %s %s %d\n", 431 - dir, op->filesrc, op->watchid); 437 + g_printerr("Add watch %s %s\n", 438 + dir, op->filesrc); 432 439 } 433 440 if (op->filesrc && strchr(op->filesrc, '/')) { 434 441 watchdir = g_strdup_printf("%s/%s", dir, op->filesrc); ··· 442 449 watchdir = g_strdup(dir); 443 450 watchfile = op->filesrc; 444 451 } 445 - watchid = 452 + *op->watchid = 446 453 qemu_file_monitor_add_watch(mon, 447 454 watchdir, 448 455 watchfile, ··· 450 457 &data, 451 458 &local_err); 452 459 g_free(watchdir); 453 - if (watchid < 0) { 460 + if (*op->watchid < 0) { 454 461 g_printerr("Unable to add watch %s", 455 462 error_get_pretty(local_err)); 456 463 goto cleanup; 457 464 } 458 - if (watchid != op->watchid) { 459 - g_printerr("Unexpected watch ID %d, wanted %d\n", 460 - watchid, op->watchid); 465 + if (debug) { 466 + g_printerr("Watch ID %" PRIx64 "\n", *op->watchid); 467 + } 468 + if (g_hash_table_contains(ids, op->watchid)) { 469 + g_printerr("Watch ID %" PRIx64 "already exists", *op->watchid); 461 470 goto cleanup; 462 471 } 472 + g_hash_table_add(ids, op->watchid); 463 473 break; 464 474 case QFILE_MONITOR_TEST_OP_DEL_WATCH: 465 475 if (debug) { 466 - g_printerr("Del watch %s %d\n", dir, op->watchid); 476 + g_printerr("Del watch %s %" PRIx64 "\n", dir, *op->watchid); 467 477 } 468 478 if (op->filesrc && strchr(op->filesrc, '/')) { 469 479 watchdir = g_strdup_printf("%s/%s", dir, op->filesrc); ··· 472 482 } else { 473 483 watchdir = g_strdup(dir); 474 484 } 485 + g_hash_table_remove(ids, op->watchid); 475 486 qemu_file_monitor_remove_watch(mon, 476 487 watchdir, 477 - op->watchid); 488 + *op->watchid); 478 489 g_free(watchdir); 479 490 break; 480 491 case QFILE_MONITOR_TEST_OP_EVENT: 481 492 if (debug) { 482 - g_printerr("Event id=%d event=%d file=%s\n", 483 - op->watchid, op->eventid, op->filesrc); 493 + g_printerr("Event id=%" PRIx64 " event=%d file=%s\n", 494 + *op->watchid, op->eventid, op->filesrc); 484 495 } 485 496 if (!qemu_file_monitor_test_expect( 486 - &data, op->watchid, op->eventid, op->filesrc)) 497 + &data, *op->watchid, op->eventid, op->filesrc)) 487 498 goto cleanup; 488 499 break; 489 500 case QFILE_MONITOR_TEST_OP_CREATE: ··· 596 607 pathsrc = pathdst = NULL; 597 608 } 598 609 610 + g_assert_cmpint(g_hash_table_size(ids), ==, 0); 611 + 599 612 err = 0; 600 613 601 614 cleanup: ··· 647 660 abort(); 648 661 } 649 662 } 663 + g_hash_table_unref(ids); 650 664 g_free(dir); 651 665 g_assert(err == 0); 652 666 }
+13 -12
util/filemonitor-inotify.c
··· 29 29 30 30 struct QFileMonitor { 31 31 int fd; 32 - int nextid; /* watch ID counter */ 33 32 QemuMutex lock; /* protects dirs & idmap */ 34 33 GHashTable *dirs; /* dirname => QFileMonitorDir */ 35 34 GHashTable *idmap; /* inotify ID => dirname */ ··· 37 36 38 37 39 38 typedef struct { 40 - int id; /* watch ID */ 39 + int64_t id; /* watch ID */ 41 40 char *filename; /* optional filter */ 42 41 QFileMonitorHandler cb; 43 42 void *opaque; ··· 46 45 47 46 typedef struct { 48 47 char *path; 49 - int id; /* inotify ID */ 48 + int inotify_id; /* inotify ID */ 49 + int next_file_id; /* file ID counter */ 50 50 GArray *watches; /* QFileMonitorWatch elements */ 51 51 } QFileMonitorDir; 52 52 ··· 126 126 g_assert_not_reached(); 127 127 } 128 128 129 - trace_qemu_file_monitor_event(mon, dir->path, name, ev->mask, dir->id); 129 + trace_qemu_file_monitor_event(mon, dir->path, name, ev->mask, 130 + dir->inotify_id); 130 131 for (i = 0; i < dir->watches->len; i++) { 131 132 QFileMonitorWatch *watch = &g_array_index(dir->watches, 132 133 QFileMonitorWatch, ··· 237 238 g_idle_add((GSourceFunc)qemu_file_monitor_free_idle, mon); 238 239 } 239 240 240 - int 241 + int64_t 241 242 qemu_file_monitor_add_watch(QFileMonitor *mon, 242 243 const char *dirpath, 243 244 const char *filename, ··· 247 248 { 248 249 QFileMonitorDir *dir; 249 250 QFileMonitorWatch watch; 250 - int ret = -1; 251 + int64_t ret = -1; 251 252 252 253 qemu_mutex_lock(&mon->lock); 253 254 dir = g_hash_table_lookup(mon->dirs, dirpath); ··· 265 266 266 267 dir = g_new0(QFileMonitorDir, 1); 267 268 dir->path = g_strdup(dirpath); 268 - dir->id = rv; 269 + dir->inotify_id = rv; 269 270 dir->watches = g_array_new(FALSE, TRUE, sizeof(QFileMonitorWatch)); 270 271 271 272 g_hash_table_insert(mon->dirs, dir->path, dir); ··· 276 277 } 277 278 } 278 279 279 - watch.id = mon->nextid++; 280 + watch.id = (((int64_t)dir->inotify_id) << 32) | dir->next_file_id++; 280 281 watch.filename = g_strdup(filename); 281 282 watch.cb = cb; 282 283 watch.opaque = opaque; ··· 297 298 298 299 void qemu_file_monitor_remove_watch(QFileMonitor *mon, 299 300 const char *dirpath, 300 - int id) 301 + int64_t id) 301 302 { 302 303 QFileMonitorDir *dir; 303 304 gsize i; ··· 322 323 } 323 324 324 325 if (dir->watches->len == 0) { 325 - inotify_rm_watch(mon->fd, dir->id); 326 - trace_qemu_file_monitor_disable_watch(mon, dir->path, dir->id); 326 + inotify_rm_watch(mon->fd, dir->inotify_id); 327 + trace_qemu_file_monitor_disable_watch(mon, dir->path, dir->inotify_id); 327 328 328 - g_hash_table_remove(mon->idmap, GINT_TO_POINTER(dir->id)); 329 + g_hash_table_remove(mon->idmap, GINT_TO_POINTER(dir->inotify_id)); 329 330 g_hash_table_remove(mon->dirs, dir->path); 330 331 331 332 if (g_hash_table_size(mon->dirs) == 0) {
+2 -2
util/filemonitor-stub.c
··· 38 38 } 39 39 40 40 41 - int 41 + int64_t 42 42 qemu_file_monitor_add_watch(QFileMonitor *mon G_GNUC_UNUSED, 43 43 const char *dirpath G_GNUC_UNUSED, 44 44 const char *filename G_GNUC_UNUSED, ··· 54 54 void 55 55 qemu_file_monitor_remove_watch(QFileMonitor *mon G_GNUC_UNUSED, 56 56 const char *dirpath G_GNUC_UNUSED, 57 - int id G_GNUC_UNUSED) 57 + int64_t id G_GNUC_UNUSED) 58 58 { 59 59 }
+3 -3
util/trace-events
··· 22 22 buffer_free(const char *buf, size_t len) "%s: capacity %zd" 23 23 24 24 # filemonitor-inotify.c 25 - qemu_file_monitor_add_watch(void *mon, const char *dirpath, const char *filename, void *cb, void *opaque, int id) "File monitor %p add watch dir='%s' file='%s' cb=%p opaque=%p id=%u" 26 - qemu_file_monitor_remove_watch(void *mon, const char *dirpath, int id) "File monitor %p remove watch dir='%s' id=%u" 25 + qemu_file_monitor_add_watch(void *mon, const char *dirpath, const char *filename, void *cb, void *opaque, int64_t id) "File monitor %p add watch dir='%s' file='%s' cb=%p opaque=%p id=%" PRId64 26 + qemu_file_monitor_remove_watch(void *mon, const char *dirpath, int64_t id) "File monitor %p remove watch dir='%s' id=%" PRId64 27 27 qemu_file_monitor_new(void *mon, int fd) "File monitor %p created fd=%d" 28 28 qemu_file_monitor_enable_watch(void *mon, const char *dirpath, int id) "File monitor %p enable watch dir='%s' id=%u" 29 29 qemu_file_monitor_disable_watch(void *mon, const char *dirpath, int id) "Fle monitor %p disable watch dir='%s' id=%u" 30 30 qemu_file_monitor_event(void *mon, const char *dirpath, const char *filename, int mask, unsigned int id) "File monitor %p event dir='%s' file='%s' mask=0x%x id=%u" 31 - qemu_file_monitor_dispatch(void *mon, const char *dirpath, const char *filename, int ev, void *cb, void *opaque, unsigned int id) "File monitor %p dispatch dir='%s' file='%s' ev=%d cb=%p opaque=%p id=%u" 31 + qemu_file_monitor_dispatch(void *mon, const char *dirpath, const char *filename, int ev, void *cb, void *opaque, int64_t id) "File monitor %p dispatch dir='%s' file='%s' ev=%d cb=%p opaque=%p id=%" PRId64 32 32 33 33 # qemu-coroutine.c 34 34 qemu_aio_coroutine_enter(void *ctx, void *from, void *to, void *opaque) "ctx %p from %p to %p opaque %p"