@@ -33,6 +33,7 @@ import (
3333 "github.com/containerd/containerd/errdefs"
3434 "github.com/containerd/containerd/filters"
3535 "github.com/containerd/containerd/log"
36+ "github.com/sirupsen/logrus"
3637
3738 "github.com/containerd/continuity"
3839 digest "github.com/opencontainers/go-digest"
@@ -477,6 +478,35 @@ func (s *store) Writer(ctx context.Context, opts ...content.WriterOpt) (content.
477478 return w , nil // lock is now held by w.
478479}
479480
481+ func (s * store ) resumeStatus (ref string , total int64 , digester digest.Digester ) (content.Status , error ) {
482+ path , _ , data := s .ingestPaths (ref )
483+ status , err := s .status (path )
484+ if err != nil {
485+ return status , errors .Wrap (err , "failed reading status of resume write" )
486+ }
487+ if ref != status .Ref {
488+ // NOTE(stevvooe): This is fairly catastrophic. Either we have some
489+ // layout corruption or a hash collision for the ref key.
490+ return status , errors .Wrapf (err , "ref key does not match: %v != %v" , ref , status .Ref )
491+ }
492+
493+ if total > 0 && status .Total > 0 && total != status .Total {
494+ return status , errors .Errorf ("provided total differs from status: %v != %v" , total , status .Total )
495+ }
496+
497+ // TODO(stevvooe): slow slow slow!!, send to goroutine or use resumable hashes
498+ fp , err := os .Open (data )
499+ if err != nil {
500+ return status , err
501+ }
502+
503+ p := bufPool .Get ().(* []byte )
504+ status .Offset , err = io .CopyBuffer (digester .Hash (), fp , * p )
505+ bufPool .Put (p )
506+ fp .Close ()
507+ return status , err
508+ }
509+
480510// writer provides the main implementation of the Writer method. The caller
481511// must hold the lock correctly and release on error if there is a problem.
482512func (s * store ) writer (ctx context.Context , ref string , total int64 , expected digest.Digest ) (content.Writer , error ) {
@@ -498,45 +528,25 @@ func (s *store) writer(ctx context.Context, ref string, total int64, expected di
498528 updatedAt time.Time
499529 )
500530
531+ foundValidIngest := false
501532 // ensure that the ingest path has been created.
502533 if err := os .Mkdir (path , 0755 ); err != nil {
503534 if ! os .IsExist (err ) {
504535 return nil , err
505536 }
506-
507- status , err := s .status (path )
508- if err != nil {
509- return nil , errors .Wrap (err , "failed reading status of resume write" )
510- }
511-
512- if ref != status .Ref {
513- // NOTE(stevvooe): This is fairly catastrophic. Either we have some
514- // layout corruption or a hash collision for the ref key.
515- return nil , errors .Wrapf (err , "ref key does not match: %v != %v" , ref , status .Ref )
516- }
517-
518- if total > 0 && status .Total > 0 && total != status .Total {
519- return nil , errors .Errorf ("provided total differs from status: %v != %v" , total , status .Total )
520- }
521-
522- // TODO(stevvooe): slow slow slow!!, send to goroutine or use resumable hashes
523- fp , err := os .Open (data )
524- if err != nil {
525- return nil , err
526- }
527-
528- p := bufPool .Get ().(* []byte )
529- offset , err = io .CopyBuffer (digester .Hash (), fp , * p )
530- bufPool .Put (p )
531- fp .Close ()
532- if err != nil {
533- return nil , err
537+ status , err := s .resumeStatus (ref , total , digester )
538+ if err == nil {
539+ foundValidIngest = true
540+ updatedAt = status .UpdatedAt
541+ startedAt = status .StartedAt
542+ total = status .Total
543+ offset = status .Offset
544+ } else {
545+ logrus .Infof ("failed to resume the status from path %s: %s. will recreate them" , path , err .Error ())
534546 }
547+ }
535548
536- updatedAt = status .UpdatedAt
537- startedAt = status .StartedAt
538- total = status .Total
539- } else {
549+ if ! foundValidIngest {
540550 startedAt = time .Now ()
541551 updatedAt = startedAt
542552
@@ -546,11 +556,11 @@ func (s *store) writer(ctx context.Context, ref string, total int64, expected di
546556 return nil , err
547557 }
548558
549- if writeTimestampFile (filepath .Join (path , "startedat" ), startedAt ); err != nil {
559+ if err := writeTimestampFile (filepath .Join (path , "startedat" ), startedAt ); err != nil {
550560 return nil , err
551561 }
552562
553- if writeTimestampFile (filepath .Join (path , "updatedat" ), startedAt ); err != nil {
563+ if err := writeTimestampFile (filepath .Join (path , "updatedat" ), startedAt ); err != nil {
554564 return nil , err
555565 }
556566
0 commit comments