func (d *Driver) deactivatePool() error {
	dev := d.Device

	volumeIDs := dev.listVolumeIDs()
	for _, id := range volumeIDs {
		volume := dev.loadVolume(id)
		if volume == nil {
			return generateError(logrus.Fields{
				LOG_FIELD_VOLUME: id,
			}, "Cannot find volume")
		}
		if err := devicemapper.RemoveDevice(id); err != nil {
			return err
		}
		log.WithFields(logrus.Fields{
			LOG_FIELD_EVENT:  LOG_EVENT_ACTIVATE,
			LOG_FIELD_VOLUME: id,
		}).Debug("Deactivated volume device")
	}

	if err := removePool(dev.ThinpoolDevice); err != nil {
		return err
	}
	log.Debug("Deactivate the pool ", dev.ThinpoolDevice)
	return nil
}
Example #2
0
// Issues the underlying dm remove operation and then waits
// for it to finish.
func (devices *DeviceSet) removeDeviceAndWait(devname string) error {
	var err error

	for i := 0; i < 1000; i++ {
		err = devicemapper.RemoveDevice(devname)
		if err == nil {
			break
		}
		if err != devicemapper.ErrBusy {
			return err
		}

		// If we see EBUSY it may be a transient error,
		// sleep a bit a retry a few times.
		devices.Unlock()
		time.Sleep(10 * time.Millisecond)
		devices.Lock()
	}
	if err != nil {
		return err
	}

	if err := devices.waitRemove(devname); err != nil {
		return err
	}
	return nil
}
Example #3
0
func removePool(poolName string) error {
	err := devicemapper.RemoveDevice(poolName)
	if err != nil {
		return err
	}
	log.Debugln("Removed pool /dev/mapper/" + poolName)

	return nil
}
func (d *Driver) DeleteVolume(id string) error {
	var err error
	volume := d.loadVolume(id)
	if volume == nil {
		return generateError(logrus.Fields{
			LOG_FIELD_VOLUME: id,
		}, "cannot find volume")
	}
	if len(volume.Snapshots) != 0 {
		for snapshotUUID := range volume.Snapshots {
			if err = d.DeleteSnapshot(snapshotUUID, volume.UUID); err != nil {
				return generateError(logrus.Fields{
					LOG_FIELD_VOLUME:   volume.UUID,
					LOG_FIELD_SNAPSHOT: snapshotUUID,
				}, "cannot remove an snapshot of volume, as part of deletion of volume")
			}
		}
	}

	if err = devicemapper.RemoveDevice(id); err != nil {
		return err
	}

	log.WithFields(logrus.Fields{
		LOG_FIELD_REASON:          LOG_REASON_START,
		LOG_FIELD_EVENT:           LOG_EVENT_REMOVE,
		LOG_FIELD_OBJECT:          LOG_OBJECT_VOLUME,
		LOG_FIELD_VOLUME:          id,
		DM_LOG_FIELD_VOLUME_DEVID: volume.DevID,
	}).Debugf("Deleting device")
	err = devicemapper.DeleteDevice(d.ThinpoolDevice, volume.DevID)
	if err != nil {
		return err
	}

	if volume.Base != "" {
		image := d.loadImage(volume.Base)
		if image == nil {
			return generateError(logrus.Fields{
				LOG_FIELD_IMAGE: volume.Base,
			}, "Cannot find volume's base image")
		}
		if _, exists := image.VolumeRef[volume.UUID]; !exists {
			return generateError(logrus.Fields{
				LOG_FIELD_IMAGE:  volume.Base,
				LOG_FIELD_VOLUME: volume.UUID,
			}, "Volume's base image doesn't refer volumev")
		}
		delete(image.VolumeRef, volume.UUID)
	}

	if err := d.deleteVolume(id); err != nil {
		return err
	}
	return nil
}
Example #5
0
func (devices *DeviceSet) deactivatePool() error {
	log.Debugf("[devmapper] deactivatePool()")
	defer log.Debugf("[devmapper] deactivatePool END")
	devname := devices.getPoolDevName()

	devinfo, err := devicemapper.GetInfo(devname)
	if err != nil {
		return err
	}
	if d, err := devicemapper.GetDeps(devname); err == nil {
		// Access to more Debug output
		log.Debugf("[devmapper] devicemapper.GetDeps() %s: %#v", devname, d)
	}
	if devinfo.Exists != 0 {
		return devicemapper.RemoveDevice(devname)
	}

	return nil
}
Example #6
0
func (d *Driver) removeDevice(name string) error {
	if err := devicemapper.BlockDeviceDiscard(name); err != nil {
		log.Debugf("Error %s when discarding %v, ignored", err, name)
	}
	for i := 0; i < 200; i++ {
		err := devicemapper.RemoveDevice(name)
		if err == nil {
			break
		}
		if err != devicemapper.ErrBusy {
			return err
		}

		// If we see EBUSY it may be a transient error,
		// sleep a bit a retry a few times.
		time.Sleep(100 * time.Millisecond)
	}
	return nil
}
Example #7
0
func (d *Driver) CloseSnapshot(id, volumeID string) error {
	snapshot, volume, err := d.getSnapshotAndVolume(id, volumeID)
	if err != nil {
		return err
	}

	log.WithFields(logrus.Fields{
		LOG_FIELD_REASON:   LOG_REASON_START,
		LOG_FIELD_EVENT:    LOG_EVENT_DEACTIVATE,
		LOG_FIELD_OBJECT:   LOG_OBJECT_SNAPSHOT,
		LOG_FIELD_SNAPSHOT: id,
	}).Debug()
	if err := devicemapper.RemoveDevice(id); err != nil {
		return err
	}
	snapshot.Activated = false

	return util.ObjectSave(volume)
}
Example #8
0
// Issues the underlying dm remove operation.
func (devices *DeviceSet) removeDevice(devname string) error {
	var err error

	logrus.Debugf("[devmapper] removeDevice START(%s)", devname)
	defer logrus.Debugf("[devmapper] removeDevice END(%s)", devname)

	for i := 0; i < 200; i++ {
		err = devicemapper.RemoveDevice(devname)
		if err == nil {
			break
		}
		if err != devicemapper.ErrBusy {
			return err
		}

		// If we see EBUSY it may be a transient error,
		// sleep a bit a retry a few times.
		devices.Unlock()
		time.Sleep(100 * time.Millisecond)
		devices.Lock()
	}

	return err
}
Example #9
0
func main() {
	root := flag.String("r", "/var/lib/docker", "Docker root dir")
	flDebug := flag.Bool("D", false, "Debug mode")

	flag.Parse()

	if *flDebug {
		os.Setenv("DEBUG", "1")
		logrus.SetLevel(logrus.DebugLevel)
	}

	if flag.NArg() < 1 {
		usage()
	}

	args := flag.Args()

	home := path.Join(*root, "devicemapper")
	devices, err := devmapper.NewDeviceSet(home, false, nil, nil, nil)
	if err != nil {
		fmt.Println("Can't initialize device mapper: ", err)
		os.Exit(1)
	}

	switch args[0] {
	case "status":
		status := devices.Status()
		fmt.Printf("Pool name: %s\n", status.PoolName)
		fmt.Printf("Data Loopback file: %s\n", status.DataLoopback)
		fmt.Printf("Metadata Loopback file: %s\n", status.MetadataLoopback)
		fmt.Printf("Sector size: %d\n", status.SectorSize)
		fmt.Printf("Data use: %d of %d (%.1f %%)\n", status.Data.Used, status.Data.Total, 100.0*float64(status.Data.Used)/float64(status.Data.Total))
		fmt.Printf("Metadata use: %d of %d (%.1f %%)\n", status.Metadata.Used, status.Metadata.Total, 100.0*float64(status.Metadata.Used)/float64(status.Metadata.Total))
		break
	case "list":
		ids := devices.List()
		sort.Strings(ids)
		for _, id := range ids {
			fmt.Println(id)
		}
		break
	case "device":
		if flag.NArg() < 2 {
			usage()
		}
		status, err := devices.GetDeviceStatus(args[1])
		if err != nil {
			fmt.Println("Can't get device info: ", err)
			os.Exit(1)
		}
		fmt.Printf("Id: %d\n", status.DeviceID)
		fmt.Printf("Size: %d\n", status.Size)
		fmt.Printf("Transaction Id: %d\n", status.TransactionID)
		fmt.Printf("Size in Sectors: %d\n", status.SizeInSectors)
		fmt.Printf("Mapped Sectors: %d\n", status.MappedSectors)
		fmt.Printf("Highest Mapped Sector: %d\n", status.HighestMappedSector)
		break
	case "resize":
		if flag.NArg() < 2 {
			usage()
		}

		size, err := byteSizeFromString(args[1])
		if err != nil {
			fmt.Println("Invalid size: ", err)
			os.Exit(1)
		}

		err = devices.ResizePool(size)
		if err != nil {
			fmt.Println("Error resizing pool: ", err)
			os.Exit(1)
		}

		break
	case "snap":
		if flag.NArg() < 3 {
			usage()
		}

		err := devices.AddDevice(args[1], args[2])
		if err != nil {
			fmt.Println("Can't create snap device: ", err)
			os.Exit(1)
		}
		break
	case "remove":
		if flag.NArg() < 2 {
			usage()
		}

		err := devicemapper.RemoveDevice(args[1])
		if err != nil {
			fmt.Println("Can't remove device: ", err)
			os.Exit(1)
		}
		break
	case "mount":
		if flag.NArg() < 3 {
			usage()
		}

		err := devices.MountDevice(args[1], args[2], "")
		if err != nil {
			fmt.Println("Can't create snap device: ", err)
			os.Exit(1)
		}
		break
	default:
		fmt.Printf("Unknown command %s\n", args[0])
		usage()

		os.Exit(1)
	}

	return
}