Skip to content

Commit

Permalink
Use hardlink to copy layer between oci and bt engine
Browse files Browse the repository at this point in the history
  • Loading branch information
hustcat committed Nov 23, 2016
1 parent 4476aca commit 7a06d0e
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 26 deletions.
5 changes: 5 additions & 0 deletions cmd/daemon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ var daemonFlags = []cli.Flag{
Value: 1 * time.Second,
Usage: "GRPC connection timeout",
},
cli.BoolFlag{
Name: "hardlink",
Usage: "use hard link to copy layer between oci engine and bt engine",
},
}

// DumpStacks dumps the runtime stack.
Expand Down Expand Up @@ -138,6 +142,7 @@ func runDaemon(context *cli.Context) error {
BtSeederServer: context.StringSlice("seeder-addr"),
UploadRateLimit: context.Int("upload-rate"),
DownloadRateLimit: context.Int("download-rate"),
UseHardlink: context.Bool("hardlink"),
}
s := make(chan os.Signal, 2048)
signal.Notify(s, syscall.SIGTERM, syscall.SIGINT)
Expand Down
1 change: 1 addition & 0 deletions daemon/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type Config struct {
Pidfile string
Root string
ConnTimeout time.Duration
UseHardlink bool

BtEnable bool
BtSeeder bool
Expand Down
72 changes: 46 additions & 26 deletions daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,27 +196,37 @@ func (daemon *Daemon) startSeedingLayer(ctx context.Context, ociImg *OciImage, d
id := distdigests.Digest(digest).Hex()
// Write layer to file
fn := daemon.btEngine.GetFilePath(id)
layerFile, err := os.Create(fn)
if err != nil {
return fmt.Errorf("Create layer file %s failed: %v", fn, err)
}
defer layerFile.Close()
if daemon.config.UseHardlink {
src, err := ociImg.layout.GetBlobPath(ctx, digest)
if err != nil {
return fmt.Errorf("Get oci blob path error: %v", err)
}
if err = os.Link(src, fn); err != nil {
return fmt.Errorf("Create hardlink error: %v", err)
}
} else {
layerFile, err := os.Create(fn)
if err != nil {
return fmt.Errorf("Create layer file %s failed: %v", fn, err)
}
defer layerFile.Close()

// Copy from OCI directory
srcFile, err := ociImg.layout.GetBlob(ctx, digest)
if err != nil {
return fmt.Errorf("Open oci layer %s error: %v", digest, err)
}
defer srcFile.Close()
// Copy from OCI directory
srcFile, err := ociImg.layout.GetBlob(ctx, digest)
if err != nil {
return fmt.Errorf("Open oci layer %s error: %v", digest, err)
}
defer srcFile.Close()

_, err = io.Copy(layerFile, srcFile)
if err != nil {
return fmt.Errorf("Copy oci layer %s error: %v", digest, err)
_, err = io.Copy(layerFile, srcFile)
if err != nil {
return fmt.Errorf("Copy oci layer %s error: %v", digest, err)
}
}

writeReport("Start seeding %s\n", id)
// Seed layer file
if err = daemon.btEngine.StartSeed(id); err != nil {
if err := daemon.btEngine.StartSeed(id); err != nil {
log.Errorf("Seed layer %s failed: %v", id, err)
} else {
log.Infof("Seed layer %s success", id)
Expand Down Expand Up @@ -336,19 +346,29 @@ func (daemon *Daemon) startLeechingLayer(ctx context.Context, ociImg *OciImage,
writeReport("%s: Copy to OCI directory\n", id)

fn := daemon.btEngine.GetFilePath(id)
layerFile, err := os.Open(fn)
if err != nil {
return fmt.Errorf("Open layer file %s failed: %v", fn, err)
}
defer layerFile.Close()
if daemon.config.UseHardlink {
dst, err := ociImg.layout.GetBlobPath(ctx, layer.Digest)
if err != nil {
return fmt.Errorf("Get oci blob path error: %v", err)
}
if err = os.Link(fn, dst); err != nil {
return fmt.Errorf("Create hardlink error: %v", err)
}
} else {
layerFile, err := os.Open(fn)
if err != nil {
return fmt.Errorf("Open layer file %s failed: %v", fn, err)
}
defer layerFile.Close()

digest, _, err := ociImg.layout.PutBlob(ctx, layerFile)
if err != nil {
return fmt.Errorf("Error to put blob %s: %v", layer.Digest, err)
}
digest, _, err := ociImg.layout.PutBlob(ctx, layerFile)
if err != nil {
return fmt.Errorf("Error to put blob %s: %v", layer.Digest, err)
}

if digest != layer.Digest {
return fmt.Errorf("Digest not match, src: %s, dest: %s", layer.Digest, digest)
if digest != layer.Digest {
return fmt.Errorf("Digest not match, src: %s, dest: %s", layer.Digest, digest)
}
}
return nil
}
Expand Down
8 changes: 8 additions & 0 deletions oci/dir.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,14 @@ func (e dirLayout) Close() error {
return os.RemoveAll(e.temp)
}

func (e dirLayout) GetBlobPath(ctx context.Context, digest string) (path string, err error) {
path, err = blobPath(digest)
if err != nil {
return "", err
}
return filepath.Join(e.path, path), nil
}

func newDirLayout(path string) (*dirLayout, error) {
layout := &dirLayout{
path: path,
Expand Down
3 changes: 3 additions & 0 deletions oci/layout.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ type Layout interface {
// Close releases all references held by the engine. Subsequent operations
// may fail.
Close() (err error)

// GetBlobPath returns a path of a blob from the image
GetBlobPath(ctx context.Context, digest string) (path string, err error)
}

// Open will create an Layout reference to the OCI image at the provided
Expand Down

0 comments on commit 7a06d0e

Please # to comment.