Пример #1
0
func TestDirectIo(t *testing.T) {
	// Make a temporary file name
	fd, err := ioutil.TempFile("", "direct_io_test")
	if err != nil {
		t.Fatal("Failed to make temp file", err)
	}
	path := fd.Name()
	fd.Close()

	// starting block
	block1 := directio.AlignedBlock(directio.BlockSize)
	for i := 0; i < len(block1); i++ {
		block1[i] = 'A'
	}

	// Write the file
	out, err := directio.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0666)
	if err != nil {
		t.Fatal("Failed to directio.OpenFile for read", err)
	}
	_, err = out.Write(block1)
	if err != nil {
		t.Fatal("Failed to write", err)
	}
	err = out.Close()
	if err != nil {
		t.Fatal("Failed to close writer", err)
	}

	// Read the file
	block2 := directio.AlignedBlock(directio.BlockSize)
	in, err := directio.OpenFile(path, os.O_RDONLY, 0666)
	if err != nil {
		t.Fatal("Failed to directio.OpenFile for write", err)
	}
	_, err = io.ReadFull(in, block2)
	if err != nil {
		t.Fatal("Failed to read", err)
	}
	err = in.Close()
	if err != nil {
		t.Fatal("Failed to close reader", err)
	}

	// Tidy
	err = os.Remove(path)
	if err != nil {
		t.Fatal("Failed to remove temp file", path, err)
	}

	// Compare
	if !bytes.Equal(block1, block2) {
		t.Fatal("Read not the same as written")
	}
}
Пример #2
0
// WriteFile writes the random source for size bytes to the file given
//
// Returns a true if the write failed, false otherwise.
func WriteFile(file string, size int64) bool {
	out, err := directio.OpenFile(file, os.O_CREATE|os.O_WRONLY, 0666)
	if err != nil {
		log.Fatalf("Couldn't open file %q for write: %s\n", file, err)
	}

	log.Printf("Writing file %q size %d\n", file, size)

	failed := false
	random := NewRandom()
	br := NewBlockReader(random, "random")
	defer br.Close()
	for size > 0 {
		block := br.Read()
		_, err := out.Write(block)
		br.Return(block)
		if err != nil {
			log.Printf("Error while writing %q\n", file)
			failed = true
			break
		}
		size -= BlockSize
		stats.Written(BlockSize)
	}

	out.Close()
	if failed {
		log.Printf("Removing incomplete file %q\n", file)
		err = os.Remove(file)
		if err != nil {
			log.Fatalf("Failed to remove incomplete file %q: %s\n", file, err)
		}
	}
	return failed
}
Пример #3
0
// ReadFile reads the file given and checks it against the random source
func ReadFile(file string) {
	in, err := directio.OpenFile(file, os.O_RDONLY, 0666)
	if err != nil {
		log.Fatalf("Failed to open %s for reading: %s\n", file, err)
	}
	defer in.Close()

	random := NewRandom()
	pos := int64(0)
	log.Printf("Reading file %q\n", file)

	// FIXME this is similar code to ReadTwoFiles
	br1 := NewBlockReader(in, file)
	defer br1.Close()
	br2 := NewBlockReader(random, "random")
	defer br2.Close()
	output := true
	for {
		block1 := br1.Read()
		block2 := br2.Read()
		if block1 == nil {
			break
		}
		if bytes.Compare(block1, block2) != 0 {
			output = outputDiff(pos, block1, block2, output)
		}
		pos += BlockSize
		br1.Return(block1)
		br2.Return(block2)
	}
}
Пример #4
0
func (s *streamSender) Run() error {
	if err := s.prepare(); err != nil {
		return err
	}

	if err := s.putHeader(&s.header); err != nil {
		return err
	}

	if len(s.srcname) > 0 {
		// always activate original lv so that target lv can be activated later
		if err := lvmutil.ActivateLv(s.vgname, s.srcname); err != nil {
			return err
		}
		defer lvmutil.DeactivateLv(s.vgname, s.srcname)
	}

	if err := lvmutil.ActivateLv(s.vgname, s.lvname); err != nil {
		return err
	}
	defer lvmutil.DeactivateLv(s.vgname, s.lvname)

	devpath := lvmutil.LvDevicePath(s.vgname, s.lvname)
	devFile, err := directio.OpenFile(devpath, os.O_RDONLY, 0644)
	if err != nil {
		return err
	}
	defer devFile.Close()

	buf := directio.AlignedBlock(int(s.header.BlockSize))

	blockSize := int64(s.header.BlockSize)
	for _, e := range s.blocks {
		if e.OpType == thindump.DeltaOpDelete {
			for i := 0; i < len(buf); i++ {
				buf[i] = 0
			}
		} else {
			if _, err := devFile.Seek(e.OriginBlock*blockSize, os.SEEK_SET); err != nil {
				return err
			}

			if _, err := io.ReadFull(devFile, buf); err != nil {
				return err
			}
		}
		if err := s.putBlock(e.OriginBlock, buf); err != nil {
			return err
		}
	}

	return nil
}
Пример #5
0
// ReadTwoFiles reads two files and checks them to be the same as it goes along.
//
// It reads the files in BlockSize chunks.
func ReadTwoFiles(file1, file2 string) {
	in1, err := directio.OpenFile(file1, os.O_RDONLY, 0666)
	if err != nil {
		log.Fatalf("Couldn't open file %q for read\n", file1)
	}
	defer in1.Close()

	in2, err := directio.OpenFile(file2, os.O_RDONLY, 0666)
	if err != nil {
		log.Fatalf("Couldn't open file %q for read\n", file2)
	}
	defer in2.Close()

	log.Printf("Reading file %q, %q\n", file1, file2)

	stats.SetMode(modeRead)
	defer stats.SetMode(modeReadDone)
	pos := int64(0)
	br1 := NewBlockReader(in1, file1)
	defer br1.Close()
	br2 := NewBlockReader(in2, file2)
	defer br2.Close()
	output := true
	for {
		block1 := br1.Read()
		block2 := br2.Read()
		if block1 == nil || block2 == nil {
			if block1 != nil || block2 != nil {
				log.Fatalf("Files %q and %q are different sizes\n", file1, file2)
			}
			break
		}
		if bytes.Compare(block1, block2) != 0 {
			output = outputDiff(pos, block1, block2, output)
		}
		pos += BlockSize
		br1.Return(block1)
		br2.Return(block2)
	}
}
Пример #6
0
func main() {
	// Get hold of the current working dir
	cwd, err := os.Getwd()
	fatalIfErr(err)

	// Create a temporary file
	fd, err := ioutil.TempFile(cwd, "sleepless")
	fatalIfErr(err)
	// We just need the file name, we're going to reopen it with the right flags
	path := fd.Name()
	fd.Close()

	// Allocate a block which will be filled with garbage on each iteration
	garbage := directio.AlignedBlock(directio.BlockSize)

	// Get ready
	out, err := directio.OpenFile(path, os.O_CREATE|os.O_RDWR|os.O_SYNC, 0600)
	fatalIfErr(err)

	// Setup signal handling
	sigint := make(chan os.Signal, 1)
	signal.Notify(sigint, os.Interrupt)
	go func() {
		<-sigint
		cleanup(out, path)
		os.Exit(0)
	}()

	// Start the main loop
	for {
		// Garbage in...
		if _, err = rand.Read(garbage); err != nil {
			cleanup(out, path)
			log.Fatal(err)
		}
		// ... garbage out
		if _, err = out.Write(garbage); err != nil {
			cleanup(out, path)
			log.Fatal(err)
		}
		// Rewind the file to the start so that it does not grow
		// indefintely
		if _, err = out.Seek(0, os.SEEK_SET); err != nil {
			cleanup(out, path)
			log.Fatal(err)
		}
		// Take a nap
		time.Sleep(10 * time.Second)
	}
}
Пример #7
0
func Open(path string, sch Scheduler) (Disk, error) {
	stat, err := os.Stat(path)
	if err != nil {
		return nil, err
	}

	f, err := directio.OpenFile(path, os.O_RDWR, 0666)
	if err != nil {
		return nil, err
	}

	return &disk{
		f:    f,
		sch:  sch,
		size: uint64(stat.Size()),
		path: path,
	}, nil
}
Пример #8
0
func (sr *streamRecver) recvNextStream() error {
	if err := sr.prepare(); err != nil {
		return err
	}

	devpath := lvmutil.LvDevicePath(sr.vgname, sr.lvname)
	devFile, err := directio.OpenFile(devpath, os.O_WRONLY, 0644)
	if err != nil {
		return err
	}
	defer devFile.Close()

	n := 8 + sr.header.BlockSize
	b := make([]byte, n+md5.Size)

	buf := directio.AlignedBlock(int(sr.header.BlockSize))

	for i := uint64(0); i < sr.header.BlockCount; i++ {
		if _, err := io.ReadFull(sr.r, b); err != nil {
			return err
		}

		sr.h.Reset()
		sr.h.Write(b[:n])
		if !bytes.Equal(sr.h.Sum(nil), b[n:n+md5.Size]) {
			return fmt.Errorf("check sum mismatch for %dst block", i)
		}

		index := int64(binary.BigEndian.Uint64(b))
		copy(buf, b[8:n])

		if _, err := devFile.Seek(int64(sr.header.BlockSize)*index, os.SEEK_SET); err != nil {
			return err
		}

		if _, err := devFile.Write(buf); err != nil {
			return err
		}
	}

	sr.prevUUID = string(sr.header.VolumeUUID[:])
	return nil
}
Пример #9
0
func (c *OSClient) open(filename string, flags int) (File, error) {
	fullpath := path.Join(c.RootDir, filename)

	var f *os.File
	var err error
	if c.Direct {
		f, err = directio.OpenFile(fullpath, flags, 0666)
	} else {
		f, err = os.OpenFile(fullpath, flags, 0644)
	}

	if err != nil {
		return nil, err
	}

	return &OSFile{
		BaseFile: BaseFile{filename: fullpath},
		file:     f,
	}, nil
}