// lockImage locks image and returns locker cookie name func (d *cephRBDVolumeDriver) lockImage(pool, imagename string) (string, error) { log.Printf("INFO: lockImage(%s/%s)", pool, imagename) ctx, err := d.openContext(pool) if err != nil { return "", err } defer d.shutdownContext(ctx) // build image struct rbdImage := rbd.GetImage(ctx, imagename) // open it (read-only) err = rbdImage.Open(true) if err != nil { log.Printf("ERROR: opening rbd image(%s): %s", imagename, err) return "", err } defer rbdImage.Close() // lock it using hostname locker := d.localLockerCookie() err = rbdImage.LockExclusive(locker) if err != nil { return locker, err } return locker, nil }
func TestNotFound(t *testing.T) { conn, _ := rados.NewConn() conn.ReadDefaultConfigFile() conn.Connect() poolname := GetUUID() err := conn.MakePool(poolname) assert.NoError(t, err) ioctx, err := conn.OpenIOContext(poolname) assert.NoError(t, err) name := GetUUID() img := rbd.GetImage(ioctx, name) err = img.Open() assert.Equal(t, err, rbd.RbdErrorNotFound) img.Remove() assert.Equal(t, err, rbd.RbdErrorNotFound) ioctx.Destroy() conn.DeletePool(poolname) conn.Shutdown() }
func (devices *RbdSet) deleteImage(info *DevInfo) error { var snapshot *rbd.Snapshot // remove image imgName := devices.getRbdImageName(info.Hash) img := rbd.GetImage(devices.ioctx, imgName) if err := img.Remove(); err != nil { log.Errorf("Rbd delete image %s failed: %v", imgName, err) return err } // hash's parent snapName := devices.getRbdSnapName(info.Hash) baseImgName := devices.getRbdImageName(info.BaseHash) parentImg := rbd.GetImage(devices.ioctx, baseImgName) if err := parentImg.Open(snapName); err != nil { log.Errorf("Rbd open image %s with snap %s failed: %v", baseImgName, snapName, err) return err } else { snapshot = parentImg.GetSnapshot(snapName) } defer parentImg.Close() // protect snapshot if err := snapshot.Unprotect(); err != nil { log.Errorf("Rbd unprotect snapshot %s failed: %v", snapName, err) return err } // remove snapshot if err := snapshot.Remove(); err != nil { log.Errorf("Rbd remove snapshot %s failed: %v", snapName, err) } // unregister it if err := devices.unRegisterDevice(info); err != nil { return err } return nil }
func (devices *RbdSet) createImage(hash, baseHash string) error { var snapshot *rbd.Snapshot baseImgName := devices.getRbdImageName(baseHash) imgName := devices.getRbdImageName(hash) img := rbd.GetImage(devices.ioctx, baseImgName) // create snapshot for hash snapName := devices.getRbdSnapName(hash) if err := img.Open(snapName); err != nil { if err != rbd.RbdErrorNotFound { log.Errorf("Rbd open image %s with snap %s failed: %v", baseImgName, snapName, err) return err } // open image without snapshot name if err = img.Open(); err != nil { log.Errorf("Rbd open image %s failed: %v", baseImgName, err) return err } // create snapshot if snapshot, err = img.CreateSnapshot(snapName); err != nil { log.Errorf("Rbd create snaphost %s failed: %v", snapName, err) img.Close() return err } } else { snapshot = img.GetSnapshot(snapName) } // open snaphost success defer img.Close() // protect snapshot if err := snapshot.Protect(); err != nil { log.Errorf("Rbd protect snapshot %s failed: %v", snapName, err) return err } // clone image _, err := img.Clone(snapName, devices.ioctx, imgName, rbd.RbdFeatureLayering) if err != nil { log.Errorf("Rbd clone snapshot %s@%s to %s failed: %v", baseImgName, snapName, imgName, err) return err } return nil }
// FIXME: getting panics when trying to run below go-ceph code, at ListLockers(): // // see https://github.com/yp-engineering/rbd-docker-plugin/issues/3 // // rbdImageIsLocked returns true if named image is already locked func (d *cephRBDVolumeDriver) rbdImageIsLocked(pool, name string) (bool, error) { if pool == "" || name == "" { return true, errors.New("rbdImageIsLocked: pool and name required") } // connext to pool ctx, err := d.openContext(pool) if err != nil { return true, err } defer d.shutdownContext(ctx) // make the image struct rbdImage := rbd.GetImage(ctx, name) // open it (read-only) err = rbdImage.Open(true) if err != nil { log.Printf("ERROR: opening rbd image(%s): %s", name, err) return true, err } defer rbdImage.Close() // check for locks -- for our purposes, with even one lock we consider image locked //lockers := []rbd.Locker{} //lockers := make([]rbd.Locker, 10) tag, lockers, err := rbdImage.ListLockers() if err != nil { log.Printf("ERROR: retrieving Lockers list for Image(%s): %s", name, err) return true, err } if len(lockers) > 0 { log.Printf("WARN: RBD Image is locked: tag=%s, lockers=%q", tag, lockers) return true, nil } return false, nil }
func TestGetImageNames(t *testing.T) { conn, _ := rados.NewConn() conn.ReadDefaultConfigFile() conn.Connect() poolname := GetUUID() err := conn.MakePool(poolname) assert.NoError(t, err) ioctx, err := conn.OpenIOContext(poolname) assert.NoError(t, err) createdList := []string{} for i := 0; i < 10; i++ { name := GetUUID() _, err := rbd.Create(ioctx, name, 1<<22) assert.NoError(t, err) createdList = append(createdList, name) } imageNames, err := rbd.GetImageNames(ioctx) assert.NoError(t, err) sort.Strings(createdList) sort.Strings(imageNames) assert.Equal(t, createdList, imageNames) for _, name := range createdList { img := rbd.GetImage(ioctx, name) err := img.Remove() assert.NoError(t, err) } ioctx.Destroy() conn.DeletePool(poolname) conn.Shutdown() }
// unlockImage releases the exclusive lock on an image func (d *cephRBDVolumeDriver) unlockImage(pool, imagename, locker string) error { if locker == "" { return errors.New(fmt.Sprintf("Unable to unlock image(%s/%s) for empty locker", pool, imagename)) } log.Printf("INFO: unlockImage(%s/%s, %s)", pool, imagename, locker) ctx, err := d.openContext(pool) if err != nil { return err } defer d.shutdownContext(ctx) // build image struct rbdImage := rbd.GetImage(ctx, imagename) // open it (read-only) err = rbdImage.Open(true) if err != nil { log.Printf("ERROR: opening rbd image(%s): %s", imagename, err) return err } defer rbdImage.Close() return rbdImage.Unlock(locker) }