Browse code

Make cookies for devicemapper operations unique

Currently, the devicemapper library sets cookies to correlate wait operations,
which must be unique (as the lvm2 library doesn't detect duplicate cookies).
The current method for cookie generation is to take the address of a cookie
variable. However, because the variable is declared on the stack, execution
patterns can lead to the cookie variable being declared at the same stack
location, which results in a high likelyhood of duplicate cookie use, which in
turn can lead to various odd lvm behaviors, which can be hard to track down
(object use before create, duplicate completions, etc). Lets guarantee that the
cookie we generate is unique by declaring it on the heap instead. This
guarantees that the address of the variable won't be reused until such time as
the UdevWait operation completes, and drops its reference to it, at which time
the gc can reclaim it.

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>

Neil Horman authored on 2017/05/10 02:42:01
Showing 1 changed files
... ...
@@ -328,11 +328,11 @@ func RemoveDevice(name string) error {
328 328
 		return err
329 329
 	}
330 330
 
331
-	var cookie uint
332
-	if err := task.setCookie(&cookie, 0); err != nil {
331
+	cookie := new(uint)
332
+	if err := task.setCookie(cookie, 0); err != nil {
333 333
 		return fmt.Errorf("devicemapper: Can not set cookie: %s", err)
334 334
 	}
335
-	defer UdevWait(&cookie)
335
+	defer UdevWait(cookie)
336 336
 
337 337
 	dmSawBusy = false // reset before the task is run
338 338
 	if err = task.run(); err != nil {
... ...
@@ -361,10 +361,10 @@ func RemoveDeviceDeferred(name string) error {
361 361
 	// set a task cookie and disable library fallback, or else libdevmapper will
362 362
 	// disable udev dm rules and delete the symlink under /dev/mapper by itself,
363 363
 	// even if the removal is deferred by the kernel.
364
-	var cookie uint
364
+	cookie := new(uint)
365 365
 	var flags uint16
366 366
 	flags = DmUdevDisableLibraryFallback
367
-	if err := task.setCookie(&cookie, flags); err != nil {
367
+	if err := task.setCookie(cookie, flags); err != nil {
368 368
 		return fmt.Errorf("devicemapper: Can not set cookie: %s", err)
369 369
 	}
370 370
 
... ...
@@ -377,7 +377,7 @@ func RemoveDeviceDeferred(name string) error {
377 377
 	// this call will not wait for the deferred removal's final executing, since no
378 378
 	// udev event will be generated, and the semaphore's value will not be incremented
379 379
 	// by udev, what UdevWait is just cleaning up the semaphore.
380
-	defer UdevWait(&cookie)
380
+	defer UdevWait(cookie)
381 381
 
382 382
 	if err = task.run(); err != nil {
383 383
 		return fmt.Errorf("devicemapper: Error running RemoveDeviceDeferred %s", err)
... ...
@@ -471,13 +471,13 @@ func CreatePool(poolName string, dataFile, metadataFile *os.File, poolBlockSize
471 471
 		return fmt.Errorf("devicemapper: Can't add target %s", err)
472 472
 	}
473 473
 
474
-	var cookie uint
474
+	cookie := new(uint)
475 475
 	var flags uint16
476 476
 	flags = DmUdevDisableSubsystemRulesFlag | DmUdevDisableDiskRulesFlag | DmUdevDisableOtherRulesFlag
477
-	if err := task.setCookie(&cookie, flags); err != nil {
477
+	if err := task.setCookie(cookie, flags); err != nil {
478 478
 		return fmt.Errorf("devicemapper: Can't set cookie %s", err)
479 479
 	}
480
-	defer UdevWait(&cookie)
480
+	defer UdevWait(cookie)
481 481
 
482 482
 	if err := task.run(); err != nil {
483 483
 		return fmt.Errorf("devicemapper: Error running deviceCreate (CreatePool) %s", err)
... ...
@@ -659,11 +659,11 @@ func ResumeDevice(name string) error {
659 659
 		return err
660 660
 	}
661 661
 
662
-	var cookie uint
663
-	if err := task.setCookie(&cookie, 0); err != nil {
662
+	cookie := new(uint)
663
+	if err := task.setCookie(cookie, 0); err != nil {
664 664
 		return fmt.Errorf("devicemapper: Can't set cookie %s", err)
665 665
 	}
666
-	defer UdevWait(&cookie)
666
+	defer UdevWait(cookie)
667 667
 
668 668
 	if err := task.run(); err != nil {
669 669
 		return fmt.Errorf("devicemapper: Error running deviceResume %s", err)
... ...
@@ -757,12 +757,12 @@ func activateDevice(poolName string, name string, deviceID int, size uint64, ext
757 757
 		return fmt.Errorf("devicemapper: Can't add node %s", err)
758 758
 	}
759 759
 
760
-	var cookie uint
761
-	if err := task.setCookie(&cookie, 0); err != nil {
760
+	cookie := new(uint)
761
+	if err := task.setCookie(cookie, 0); err != nil {
762 762
 		return fmt.Errorf("devicemapper: Can't set cookie %s", err)
763 763
 	}
764 764
 
765
-	defer UdevWait(&cookie)
765
+	defer UdevWait(cookie)
766 766
 
767 767
 	if err := task.run(); err != nil {
768 768
 		return fmt.Errorf("devicemapper: Error running deviceCreate (ActivateDevice) %s", err)