// New returns a new local disk storage implementation at the provided // root directory, which must already exist. func New(root string) (*DiskStorage, error) { // Local disk. fi, err := os.Stat(root) if os.IsNotExist(err) { return nil, fmt.Errorf("Storage root %q doesn't exist", root) } if err != nil { return nil, fmt.Errorf("Failed to stat directory %q: %v", root, err) } if !fi.IsDir() { return nil, fmt.Errorf("Storage root %q exists but is not a directory.", root) } ds := &DiskStorage{ root: root, dirLockMu: new(sync.RWMutex), gen: local.NewGenerationer(root), } if err := ds.migrate3to2(); err != nil { return nil, fmt.Errorf("Error updating localdisk format: %v", err) } if _, _, err := ds.StorageGeneration(); err != nil { return nil, fmt.Errorf("Error initialization generation for %q: %v", root, err) } return ds, nil }
// newStorage returns a new storage in path root with the given maxFileSize, // or defaultMaxFileSize (512MB) if <= 0 func newStorage(root string, maxFileSize int64) (*storage, error) { fi, err := os.Stat(root) if os.IsNotExist(err) { return nil, fmt.Errorf("storage root %q doesn't exist", root) } if err != nil { return nil, fmt.Errorf("Failed to stat directory %q: %v", root, err) } if !fi.IsDir() { return nil, fmt.Errorf("storage root %q exists but is not a directory.", root) } index, _, err := kvfile.NewStorage(filepath.Join(root, "index.kv")) if maxFileSize <= 0 { maxFileSize = defaultMaxFileSize } s := &storage{root: root, index: index, maxFileSize: maxFileSize, Generationer: local.NewGenerationer(root), } if err := s.openCurrent(); err != nil { return nil, err } if _, _, err := s.StorageGeneration(); err != nil { return nil, fmt.Errorf("Error initialization generation for %q: %v", root, err) } return s, nil }
// New returns a new local disk storage implementation at the provided // root directory, which must already exist. func New(root string) (*DiskStorage, error) { // Local disk. fi, err := os.Stat(root) if os.IsNotExist(err) { // As a special case, we auto-created the "packed" directory for subpacked. if filepath.Base(root) == "packed" { if err := os.Mkdir(root, 0700); err != nil { return nil, fmt.Errorf("failed to mkdir packed directory: %v", err) } fi, err = os.Stat(root) } else { return nil, fmt.Errorf("Storage root %q doesn't exist", root) } } if err != nil { return nil, fmt.Errorf("Failed to stat directory %q: %v", root, err) } if !fi.IsDir() { return nil, fmt.Errorf("Storage root %q exists but is not a directory.", root) } ds := &DiskStorage{ root: root, dirLockMu: new(sync.RWMutex), gen: local.NewGenerationer(root), } if err := ds.migrate3to2(); err != nil { return nil, fmt.Errorf("Error updating localdisk format: %v", err) } if _, _, err := ds.StorageGeneration(); err != nil { return nil, fmt.Errorf("Error initialization generation for %q: %v", root, err) } return ds, nil }
// newStorage returns a new storage in path root with the given maxFileSize, // or defaultMaxFileSize (512MB) if <= 0 func newStorage(root string, maxFileSize int64, indexConf jsonconfig.Obj) (s *storage, err error) { fi, err := os.Stat(root) if os.IsNotExist(err) { return nil, fmt.Errorf("storage root %q doesn't exist", root) } if err != nil { return nil, fmt.Errorf("Failed to stat directory %q: %v", root, err) } if !fi.IsDir() { return nil, fmt.Errorf("storage root %q exists but is not a directory.", root) } var index sorted.KeyValue if len(indexConf) > 0 { index, err = sorted.NewKeyValue(indexConf) } else { index, err = kvfile.NewStorage(filepath.Join(root, indexKV)) } if err != nil { return nil, err } defer func() { if err != nil { index.Close() } }() if maxFileSize <= 0 { maxFileSize = defaultMaxFileSize } // Be consistent with trailing slashes. Makes expvar stats for total // reads/writes consistent across diskpacked targets, regardless of what // people put in their low level config. root = strings.TrimRight(root, `\/`) s = &storage{ root: root, index: index, maxFileSize: maxFileSize, Generationer: local.NewGenerationer(root), } s.mu.Lock() defer s.mu.Unlock() if err := s.openAllPacks(); err != nil { return nil, err } if _, _, err := s.StorageGeneration(); err != nil { return nil, fmt.Errorf("Error initialization generation for %q: %v", root, err) } return s, nil }
// New returns a new local disk storage implementation at the provided // root directory, which must already exist. func New(root string) (*DiskStorage, error) { // Local disk. fi, err := os.Stat(root) if os.IsNotExist(err) { // As a special case, we auto-created the "packed" directory for subpacked. if filepath.Base(root) == "packed" { if err := os.Mkdir(root, 0700); err != nil { return nil, fmt.Errorf("failed to mkdir packed directory: %v", err) } fi, err = os.Stat(root) } else { return nil, fmt.Errorf("Storage root %q doesn't exist", root) } } if err != nil { return nil, fmt.Errorf("Failed to stat directory %q: %v", root, err) } if !fi.IsDir() { return nil, fmt.Errorf("Storage root %q exists but is not a directory.", root) } ds := &DiskStorage{ root: root, dirLockMu: new(sync.RWMutex), gen: local.NewGenerationer(root), } if err := ds.migrate3to2(); err != nil { return nil, fmt.Errorf("Error updating localdisk format: %v", err) } if _, _, err := ds.StorageGeneration(); err != nil { return nil, fmt.Errorf("Error initialization generation for %q: %v", root, err) } ul, err := osutil.MaxFD() if err != nil { if err == osutil.ErrNotSupported { // Do not set the gate on Windows, since we don't know the ulimit. return ds, nil } return nil, err } if ul < minFDLimit { return nil, fmt.Errorf("The max number of open file descriptors on your system (ulimit -n) is too low. Please fix it with 'ulimit -S -n X' with X being at least %d.", recommendedFDLimit) } // Setting the gate to 80% of the ulimit, to leave a bit of room for other file ops happening in Camlistore. // TODO(mpl): make this used and enforced Camlistore-wide. Issue #837. ds.tmpFileGate = syncutil.NewGate(int(ul * 80 / 100)) return ds, nil }