func (devices *DeviceSet) AddDevice(hash, baseHash string) error { baseInfo, err := devices.lookupDevice(baseHash) if err != nil { return err } baseInfo.lock.Lock() defer baseInfo.lock.Unlock() devices.Lock() defer devices.Unlock() if info, _ := devices.lookupDevice(hash); info != nil { return fmt.Errorf("device %s already exists", hash) } deviceId := devices.NextDeviceId if err := devicemapper.CreateSnapDevice(devices.getPoolDevName(), &deviceId, baseInfo.Name(), baseInfo.DeviceId); err != nil { log.Debugf("Error creating snap device: %s", err) return err } // Ids are 24bit, so wrap around devices.NextDeviceId = (deviceId + 1) & 0xffffff if _, err := devices.registerDevice(deviceId, hash, baseInfo.Size); err != nil { devicemapper.DeleteDevice(devices.getPoolDevName(), deviceId) log.Debugf("Error registering device: %s", err) return err } return nil }
func (d *Driver) CreateSnapshot(req Request) error { var err error d.mutex.Lock() defer d.mutex.Unlock() id := req.Name volumeID, err := util.GetFieldFromOpts(OPT_VOLUME_NAME, req.Options) if err != nil { return err } volume := d.blankVolume(volumeID) if err := util.ObjectLoad(volume); err != nil { return err } devID, err := d.allocateDevID() if err != nil { return err } snapshot, exists := volume.Snapshots[id] if exists { return generateError(logrus.Fields{ LOG_FIELD_VOLUME: volumeID, LOG_FIELD_SNAPSHOT: id, }, "Already has snapshot with name") } log.WithFields(logrus.Fields{ LOG_FIELD_REASON: LOG_REASON_START, LOG_FIELD_EVENT: LOG_EVENT_CREATE, LOG_FIELD_OBJECT: LOG_OBJECT_SNAPSHOT, LOG_FIELD_SNAPSHOT: id, LOG_FIELD_VOLUME: volumeID, DM_LOG_FIELD_VOLUME_DEVID: volume.DevID, DM_LOG_FIELD_SNAPSHOT_DEVID: devID, }).Debugf("Creating snapshot") err = devicemapper.CreateSnapDevice(d.ThinpoolDevice, devID, volumeID, volume.DevID) if err != nil { return err } log.Debugf("Created snapshot device") snapshot = Snapshot{ Name: id, CreatedTime: util.Now(), DevID: devID, Activated: false, } volume.Snapshots[id] = snapshot if err := util.ObjectSave(volume); err != nil { return err } return nil }
func (devices *DeviceSet) createRegisterSnapDevice(hash string, baseInfo *DevInfo) error { deviceId, err := devices.getNextFreeDeviceId() if err != nil { return err } if err := devices.openTransaction(hash, deviceId); err != nil { log.Debugf("Error opening transaction hash = %s deviceId = %d", hash, deviceId) devices.markDeviceIdFree(deviceId) return err } for { if err := devicemapper.CreateSnapDevice(devices.getPoolDevName(), deviceId, baseInfo.Name(), baseInfo.DeviceId); err != nil { if devicemapper.DeviceIdExists(err) { // Device Id already exists. This should not // happen. Now we have a mechianism to find // a free device Id. So something is not right. // Give a warning and continue. log.Errorf("Warning: Device Id %d exists in pool but it is supposed to be unused", deviceId) deviceId, err = devices.getNextFreeDeviceId() if err != nil { return err } // Save new device id into transaction devices.refreshTransaction(deviceId) continue } log.Debugf("Error creating snap device: %s", err) devices.markDeviceIdFree(deviceId) return err } break } if _, err := devices.registerDevice(deviceId, hash, baseInfo.Size, devices.OpenTransactionId); err != nil { devicemapper.DeleteDevice(devices.getPoolDevName(), deviceId) devices.markDeviceIdFree(deviceId) log.Debugf("Error registering device: %s", err) return err } if err := devices.closeTransaction(); err != nil { devices.unregisterDevice(deviceId, hash) devicemapper.DeleteDevice(devices.getPoolDevName(), deviceId) devices.markDeviceIdFree(deviceId) return err } return nil }
func (d *Driver) CreateSnapshot(id, volumeID string) error { var err error volume := d.loadVolume(volumeID) if volume == nil { return generateError(logrus.Fields{ LOG_FIELD_VOLUME: volumeID, }, "Cannot find volume") } devID, err := d.allocateDevID() if err != nil { return err } snapshot, exists := volume.Snapshots[id] if exists { return generateError(logrus.Fields{ LOG_FIELD_VOLUME: volumeID, LOG_FIELD_SNAPSHOT: id, }, "Already has snapshot with uuid") } log.WithFields(logrus.Fields{ LOG_FIELD_REASON: LOG_REASON_START, LOG_FIELD_EVENT: LOG_EVENT_CREATE, LOG_FIELD_OBJECT: LOG_OBJECT_SNAPSHOT, LOG_FIELD_SNAPSHOT: id, LOG_FIELD_VOLUME: volumeID, DM_LOG_FIELD_VOLUME_DEVID: volume.DevID, DM_LOG_FIELD_SNAPSHOT_DEVID: devID, }).Debugf("Creating snapshot") err = devicemapper.CreateSnapDevice(d.ThinpoolDevice, devID, volumeID, volume.DevID) if err != nil { return err } log.Debugf("Created snapshot device") snapshot = Snapshot{ DevID: devID, Activated: false, } volume.Snapshots[id] = snapshot if err := d.saveVolume(volume); err != nil { return err } return nil }