// Open opens the named kv DB file for reading/writing. It // creates the file if it does not exist yet. func Open(dbFile string, opts *kv.Options) (*kv.DB, error) { createOpen := kv.Open verb := "opening" if _, err := os.Stat(dbFile); os.IsNotExist(err) { createOpen = kv.Create verb = "creating" } if opts == nil { opts = &kv.Options{} } if opts.Locker == nil { opts.Locker = func(dbFile string) (io.Closer, error) { lkfile := dbFile + ".lock" cl, err := lock.Lock(lkfile) if err != nil { return nil, fmt.Errorf("failed to acquire lock on %s: %v", lkfile, err) } return cl, nil } } if v, _ := strconv.ParseBool(os.Getenv("CAMLI_KV_VERIFY")); v { opts.VerifyDbBeforeOpen = true opts.VerifyDbAfterOpen = true opts.VerifyDbBeforeClose = true opts.VerifyDbAfterClose = true } db, err := createOpen(dbFile, opts) if err != nil { return nil, fmt.Errorf("error %s %s: %v", verb, dbFile, err) } return db, nil }
// openForWrite will create or open pack file n for writes, create a lock // visible external to the process and seek to the end of the file ready for // appending new data. // This function is not thread safe, s.mu should be locked by the caller. func (s *storage) openForWrite(n int) error { fn := s.filename(n) l, err := lock.Lock(fn + ".lock") if err != nil { return err } f, err := os.OpenFile(fn, os.O_RDWR|os.O_CREATE, 0666) if err != nil { l.Close() return err } openFdsVar.Add(s.root, 1) debug.Printf("diskpacked: opened for write %q", fn) s.size, err = f.Seek(0, os.SEEK_END) if err != nil { return err } s.writer = f s.writeLock = l return nil }