func (devices *DeviceSet) activateDeviceIfNeeded(info *DevInfo) error { log.Debugf("activateDeviceIfNeeded(%v)", info.Hash) if devinfo, _ := devicemapper.GetInfo(info.Name()); devinfo != nil && devinfo.Exists != 0 { return nil } return devicemapper.ActivateDevice(devices.getPoolDevName(), info.Name(), info.DeviceId, info.Size) }
func (devices *DeviceSet) activateDeviceIfNeeded(info *DevInfo) error { logrus.Debugf("activateDeviceIfNeeded(%v)", info.Hash) // Make sure deferred removal on device is canceled, if one was // scheduled. if err := devices.cancelDeferredRemoval(info); err != nil { return fmt.Errorf("Deivce Deferred Removal Cancellation Failed: %s", err) } if devinfo, _ := devicemapper.GetInfo(info.Name()); devinfo != nil && devinfo.Exists != 0 { return nil } return devicemapper.ActivateDevice(devices.getPoolDevName(), info.Name(), info.DeviceId, info.Size) }
func (d *Driver) activatePool() error { dev := d.Device if _, err := os.Stat(dev.ThinpoolDevice); err == nil { log.Debug("Found created pool, skip pool reinit") return nil } dataDev, err := os.Open(dev.DataDevice) if err != nil { return err } defer dataDev.Close() metadataDev, err := os.Open(dev.MetadataDevice) if err != nil { return err } defer metadataDev.Close() if err := createPool(filepath.Base(dev.ThinpoolDevice), dataDev, metadataDev, uint32(dev.ThinpoolBlockSize)); err != nil { return err } log.Debug("Reinitialized the existing pool ", dev.ThinpoolDevice) volumeIDs, err := dev.listVolumeIDs() if err != nil { return err } for _, id := range volumeIDs { volume := d.blankVolume(id) if err := util.ObjectLoad(volume); err != nil { return err } if err := devicemapper.ActivateDevice(dev.ThinpoolDevice, id, volume.DevID, uint64(volume.Size)); err != nil { return err } log.WithFields(logrus.Fields{ LOG_FIELD_EVENT: LOG_EVENT_ACTIVATE, LOG_FIELD_VOLUME: id, }).Debug("Reactivated volume device") } return nil }
func (d *Driver) OpenSnapshot(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_ACTIVATE, LOG_FIELD_OBJECT: LOG_OBJECT_SNAPSHOT, LOG_FIELD_VOLUME: volumeID, LOG_FIELD_SNAPSHOT: id, LOG_FIELD_SIZE: volume.Size, DM_LOG_FIELD_SNAPSHOT_DEVID: snapshot.DevID, }).Debug() if err = devicemapper.ActivateDevice(d.ThinpoolDevice, id, snapshot.DevID, uint64(volume.Size)); err != nil { return err } snapshot.Activated = true return util.ObjectSave(volume) }
func (d *Driver) CreateVolume(id string, opts map[string]string) error { var ( size int64 err error ) backupURL := opts[convoydriver.OPT_BACKUP_URL] if backupURL != "" { objVolume, err := objectstore.LoadVolume(backupURL) if err != nil { return err } if objVolume.Driver != d.Name() { return fmt.Errorf("Cannot restore backup of %v to %v", objVolume.Driver, d.Name()) } size, err = d.getSize(opts, objVolume.Size) if err != nil { return err } if size != objVolume.Size { return fmt.Errorf("Volume size must match with backup's size") } } else { size, err = d.getSize(opts, d.DefaultVolumeSize) if err != nil { return err } } if size%(d.ThinpoolBlockSize*SECTOR_SIZE) != 0 { return fmt.Errorf("Size must be multiple of block size") } volume := d.blankVolume(id) exists, err := util.ObjectExists(volume) if err != nil { return err } if exists { return generateError(logrus.Fields{ LOG_FIELD_VOLUME: id, }, "Already has volume with specific uuid") } devID, err := d.allocateDevID() if err != nil { return err } log.WithFields(logrus.Fields{ LOG_FIELD_REASON: LOG_REASON_START, LOG_FIELD_EVENT: LOG_EVENT_CREATE, LOG_FIELD_OBJECT: LOG_OBJECT_VOLUME, LOG_FIELD_VOLUME: id, DM_LOG_FIELD_VOLUME_DEVID: devID, }).Debugf("Creating volume") err = devicemapper.CreateDevice(d.ThinpoolDevice, devID) if err != nil { return err } log.WithFields(logrus.Fields{ LOG_FIELD_REASON: LOG_REASON_START, LOG_FIELD_EVENT: LOG_EVENT_ACTIVATE, LOG_FIELD_OBJECT: LOG_OBJECT_VOLUME, LOG_FIELD_VOLUME: id, DM_LOG_FIELD_VOLUME_DEVID: devID, }).Debugf("Activating device for volume") err = devicemapper.ActivateDevice(d.ThinpoolDevice, id, devID, uint64(size)) if err != nil { log.WithFields(logrus.Fields{ LOG_FIELD_REASON: LOG_REASON_ROLLBACK, LOG_FIELD_EVENT: LOG_EVENT_REMOVE, LOG_FIELD_OBJECT: LOG_OBJECT_VOLUME, LOG_FIELD_VOLUME: id, DM_LOG_FIELD_VOLUME_DEVID: devID, }).Debugf("Removing device for volume due to fail to activate") if err := devicemapper.DeleteDevice(d.ThinpoolDevice, devID); err != nil { log.WithFields(logrus.Fields{ LOG_FIELD_REASON: LOG_REASON_FAILURE, LOG_FIELD_EVENT: LOG_EVENT_REMOVE, LOG_FIELD_OBJECT: LOG_OBJECT_VOLUME, LOG_FIELD_VOLUME: id, DM_LOG_FIELD_VOLUME_DEVID: devID, }).Debugf("Failed to remove device") } return err } volume.DevID = devID volume.Size = size volume.Snapshots = make(map[string]Snapshot) if err := util.ObjectSave(volume); err != nil { return err } dev, err := d.GetVolumeDevice(id) if err != nil { return err } if backupURL == "" { // format the device if _, err := util.Execute("mkfs", []string{"-t", "ext4", dev}); err != nil { return err } } else { if err := objectstore.RestoreDeltaBlockBackup(backupURL, dev); err != nil { return err } } return nil }
func (d *Driver) CreateVolume(id, baseID string, size int64) error { var err error if size%(d.ThinpoolBlockSize*SECTOR_SIZE) != 0 { return fmt.Errorf("Size must be multiple of block size") } volume := d.loadVolume(id) if volume != nil { return generateError(logrus.Fields{ LOG_FIELD_VOLUME: id, }, "Already has volume with specific uuid") } var image *Image if baseID != "" { image = d.loadImage(baseID) if image == nil { return generateError(logrus.Fields{ LOG_FIELD_IMAGE: baseID, }, "Cannot find activated base image") } if _, err := os.Stat(image.Device); err != nil { return generateError(logrus.Fields{ LOG_FIELD_IMAGE_DEV: image.Device, }, "Base image device doesn't exist") } if size != image.Size { return generateError(logrus.Fields{ LOG_FIELD_IMAGE: baseID, LOG_FIELD_VOLUME: id, }, "Volume has different size(%v) than base image(%v)", size, image.Size) } } devID, err := d.allocateDevID() if err != nil { return err } log.WithFields(logrus.Fields{ LOG_FIELD_REASON: LOG_REASON_START, LOG_FIELD_EVENT: LOG_EVENT_CREATE, LOG_FIELD_OBJECT: LOG_OBJECT_VOLUME, LOG_FIELD_VOLUME: id, LOG_FIELD_IMAGE: baseID, DM_LOG_FIELD_VOLUME_DEVID: devID, }).Debugf("Creating volume") err = devicemapper.CreateDevice(d.ThinpoolDevice, devID) if err != nil { return err } log.WithFields(logrus.Fields{ LOG_FIELD_REASON: LOG_REASON_START, LOG_FIELD_EVENT: LOG_EVENT_ACTIVATE, LOG_FIELD_OBJECT: LOG_OBJECT_VOLUME, LOG_FIELD_VOLUME: id, LOG_FIELD_IMAGE: baseID, DM_LOG_FIELD_VOLUME_DEVID: devID, }).Debugf("Activating device for volume") if image == nil { err = devicemapper.ActivateDevice(d.ThinpoolDevice, id, devID, uint64(size)) } else { err = devicemapper.ActivateDeviceWithExternal(d.ThinpoolDevice, id, devID, uint64(size), image.Device) } if err != nil { log.WithFields(logrus.Fields{ LOG_FIELD_REASON: LOG_REASON_ROLLBACK, LOG_FIELD_EVENT: LOG_EVENT_REMOVE, LOG_FIELD_OBJECT: LOG_OBJECT_VOLUME, LOG_FIELD_VOLUME: id, LOG_FIELD_IMAGE: baseID, DM_LOG_FIELD_VOLUME_DEVID: devID, }).Debugf("Removing device for volume due to fail to activate") if err := devicemapper.DeleteDevice(d.ThinpoolDevice, devID); err != nil { log.WithFields(logrus.Fields{ LOG_FIELD_REASON: LOG_REASON_FAILURE, LOG_FIELD_EVENT: LOG_EVENT_REMOVE, LOG_FIELD_OBJECT: LOG_OBJECT_VOLUME, LOG_FIELD_VOLUME: id, LOG_FIELD_IMAGE: baseID, DM_LOG_FIELD_VOLUME_DEVID: devID, }).Debugf("Failed to remove device") } return err } volume = &Volume{ UUID: id, DevID: devID, Size: size, Snapshots: make(map[string]Snapshot), } if image != nil { volume.Base = image.UUID image.VolumeRef[id] = true if err := d.saveImage(image); err != nil { return err } } if err := d.saveVolume(volume); err != nil { return err } return nil }