func bsnapListAction(cmd *cobra.Command, args []string) {
	if len(args) != 1 {
		cmd.Usage()
		os.Exit(1)
	}
	vol := args[0]
	srv := createServer()
	defer srv.Close()
	blockvol, err := block.OpenBlockVolume(srv, vol)
	if err != nil {
		die("couldn't open block volume %s: %v", vol, err)
	}
	snaps, err := blockvol.GetSnapshots()
	if err != nil {
		die("couldn't get snapshots for block volume %s: %v", vol, err)
	}
	table := NewTableWriter(os.Stdout)
	table.SetHeader([]string{"Snapshot Name", "Timestamp"})
	for _, x := range snaps {
		table.Append([]string{
			x.Name,
			x.When.Format(time.RFC3339),
		})
	}
	if !outputAsCSV {
		fmt.Printf("Volume: %s\n", vol)
		table.Render()
	} else {
		table.RenderCSV()
	}
}
func (f *finder) FindDevice(name string) (nbd.Device, error) {
	blockvol, err := block.OpenBlockVolume(f.srv, name)
	if err != nil {
		return nil, err
	}

	return blockvol.OpenBlockFile()
}
Beispiel #3
0
func openVol(t *testing.T, server *torus.Server, volname string) *block.BlockFile {
	blockvol, err := block.OpenBlockVolume(server, volname)
	if err != nil {
		t.Fatalf("couldn't open block volume %s: %v", volname, err)
	}
	f, err := blockvol.OpenBlockFile()
	if err != nil {
		t.Fatalf("couldn't open blockfile %s: %v", volname, err)
	}
	return f
}
Beispiel #4
0
func BenchmarkLoadThree(b *testing.B) {
	b.StopTimer()

	servers, mds := ringN(b, 3)
	client := newServer(b, mds)
	err := distributor.OpenReplication(client)
	if err != nil {
		b.Fatal(err)
	}
	defer client.Close()
	size := BlockSize * 100
	data := makeTestData(size)

	b.StartTimer()

	for i := 0; i < b.N; i++ {
		input := bytes.NewReader(data)
		volname := fmt.Sprintf("testvol-%d", i)

		err = block.CreateBlockVolume(client.MDS, volname, uint64(size))
		if err != nil {
			b.Fatalf("couldn't create block volume %s: %v", volname, err)
		}
		blockvol, err := block.OpenBlockVolume(client, volname)
		if err != nil {
			b.Fatalf("couldn't open block volume %s: %v", volname, err)
		}
		f, err := blockvol.OpenBlockFile()
		if err != nil {
			b.Fatalf("couldn't open blockfile %s: %v", volname, err)
		}
		copied, err := io.Copy(f, input)
		if err != nil {
			b.Fatalf("couldn't copy: %v", err)
		}
		err = f.Sync()
		if err != nil {
			b.Fatalf("couldn't sync: %v", err)
		}
		err = f.Close()
		if err != nil {
			b.Fatalf("couldn't close: %v", err)
		}

		b.Logf("copied %d bytes", copied)
	}

	b.SetBytes(int64(size))

	b.StopTimer()
	closeAll(b, servers...)
	b.StartTimer()
}
Beispiel #5
0
func blockDumpAction(cmd *cobra.Command, args []string) error {
	if len(args) != 2 {
		return torus.ErrUsage
	}
	output, err := getWriterFromArg(args[1])
	if err != nil {
		return fmt.Errorf("couldn't open output: %v", err)
	}
	srv := createServer()
	defer srv.Close()
	blockvol, err := block.OpenBlockVolume(srv, args[0])
	if err != nil {
		return fmt.Errorf("couldn't open block volume %s: %v", args[0], err)
	}
	tempsnap := fmt.Sprintf("temp-dump-%d", os.Getpid())
	err = blockvol.SaveSnapshot(tempsnap)
	if err != nil {
		return fmt.Errorf("couldn't snapshot: %v", err)
	}
	bf, err := blockvol.OpenSnapshot(tempsnap)
	if err != nil {
		return fmt.Errorf("couldn't open snapshot: %v", err)
	}

	size := int64(bf.Size())
	if progress {
		pb := progressutil.NewCopyProgressPrinter()
		pb.AddCopy(bf, path.Base(args[0]), size, output)
		err := pb.PrintAndWait(os.Stderr, 500*time.Millisecond, nil)
		if err != nil {
			return fmt.Errorf("couldn't copy: %v", err)
		}
	} else {
		n, err := io.Copy(output, bf)
		if err != nil {
			return fmt.Errorf("couldn't copy: %v", err)
		}

		if n != size {
			return fmt.Errorf("short read of %q", args[0])
		}
	}

	err = blockvol.DeleteSnapshot(tempsnap)
	if err != nil {
		return fmt.Errorf("couldn't delete snapshot: %v", err)
	}
	fmt.Printf("copied %d bytes\n", size)
	return nil
}
Beispiel #6
0
func nbdAction(cmd *cobra.Command, args []string) error {
	if len(detachDevice) > 0 && len(args) == 0 {
		if err := nbd.Detach(detachDevice); err != nil {
			return fmt.Errorf("failed to detach: %v", err)
		}
		return nil
	}

	if len(args) != 1 && len(args) != 2 {
		return torus.ErrUsage
	}

	var knownDev string
	if len(args) == 2 {
		knownDev = args[1]
	}

	srv := createServer()

	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, os.Interrupt)

	closer := make(chan bool)
	go func() {
		for _ = range signalChan {
			fmt.Println("\nReceived an interrupt, disconnecting...")
			close(closer)
		}
	}()
	defer srv.Close()
	blockvol, err := block.OpenBlockVolume(srv, args[0])
	if err != nil {
		return fmt.Errorf("server doesn't support block volumes: %s", err)
	}

	f, err := blockvol.OpenBlockFile()
	if err != nil {
		if err == torus.ErrLocked {
			return fmt.Errorf("volume %s is already mounted on another host", args[0])
		}
		return fmt.Errorf("can't open block volume: %s", err)
	}
	defer f.Close()
	err = connectNBD(srv, f, knownDev, closer)
	if err != nil {
		return err
	}
	return nil
}
func nbdAction(cmd *cobra.Command, args []string) {
	if len(args) != 1 && len(args) != 2 {
		cmd.Usage()
		os.Exit(1)
	}

	var knownDev string
	if len(args) == 2 {
		knownDev = args[1]
	}

	srv := createServer()

	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, os.Interrupt)

	closer := make(chan bool)
	go func() {
		for _ = range signalChan {
			fmt.Println("\nReceived an interrupt, disconnecting...")
			close(closer)
		}
	}()
	defer srv.Close()
	blockvol, err := block.OpenBlockVolume(srv, args[0])
	if err != nil {
		fmt.Fprintf(os.Stderr, "server doesn't support block volumes: %s\n", err)
		os.Exit(1)
	}

	f, err := blockvol.OpenBlockFile()
	if err != nil {
		if err == torus.ErrLocked {
			fmt.Fprintf(os.Stderr, "volume %s is already mounted on another host\n", args[0])
		} else {
			fmt.Fprintf(os.Stderr, "can't open block volume: %s\n", err)
		}
		os.Exit(1)
	}
	defer f.Close()
	err = connectNBD(srv, f, knownDev, closer)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", err)
		os.Exit(1)
	}
}
func bsnapCreateAction(cmd *cobra.Command, args []string) {
	if len(args) != 1 {
		cmd.Usage()
		os.Exit(1)
	}
	vol := ParseSnapName(args[0])
	if vol.Snapshot == "" {
		die("can't create snapshot without a name, please use the form VOLUME@SNAPSHOT_NAME")
	}
	srv := createServer()
	defer srv.Close()
	blockvol, err := block.OpenBlockVolume(srv, vol.Volume)
	if err != nil {
		die("couldn't open block volume %s: %v", vol.Volume, err)
	}
	err = blockvol.SaveSnapshot(vol.Snapshot)
	if err != nil {
		die("couldn't snapshot: %v", err)
	}
}
Beispiel #9
0
func bsnapRestoreAction(cmd *cobra.Command, args []string) error {
	if len(args) != 1 {
		return torus.ErrUsage
	}
	vol := ParseSnapName(args[0])
	if vol.Snapshot == "" {
		return fmt.Errorf("can't restore a snapshot without a name, please use the form VOLUME@SNAPSHOT_NAME")
	}
	srv := createServer()
	defer srv.Close()
	blockvol, err := block.OpenBlockVolume(srv, vol.Volume)
	if err != nil {
		return fmt.Errorf("couldn't open block volume %s: %v", vol.Volume, err)
	}
	err = blockvol.RestoreSnapshot(vol.Snapshot)
	if err != nil {
		return fmt.Errorf("couldn't restore snapshot: %v", err)
	}
	return nil
}
Beispiel #10
0
func tcmuAction(cmd *cobra.Command, args []string) error {
	if len(args) != 1 {
		return torus.ErrUsage
	}

	srv := createServer()

	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, os.Interrupt)

	closer := make(chan bool)
	go func() {
		for range signalChan {
			fmt.Println("\nReceived an interrupt, disconnecting...")
			close(closer)
		}
	}()
	defer srv.Close()
	blockvol, err := block.OpenBlockVolume(srv, args[0])
	if err != nil {
		return fmt.Errorf("server doesn't support block volumes: %s", err)
	}

	f, err := blockvol.OpenBlockFile()
	if err != nil {
		if err == torus.ErrLocked {
			return fmt.Errorf("volume %s is already mounted on another host", args[0])
		}
		return fmt.Errorf("can't open block volume: %s", err)
	}
	defer f.Close()
	err = torustcmu.ConnectAndServe(f, args[0], closer)
	if err != nil {
		return fmt.Errorf("failed to serve volume using SCSI: %s", err)
	}
	return nil
}
// testAoEServer sets up a Torus AoE server and returns:
//  - an io.Reader which contains the server's response to a request
//  - an io.Writer which can be used to issue a request to the server
//  - a closure which can be used to run the server for a single
//    request/response cycle
//  - a closure which can be used to tear down all server resources
func testAoEServer(t *testing.T) (response io.Reader, request io.Writer, run func() error, done func()) {
	ts := torus.NewMemoryServer()

	mds, err := temp.NewTemp(ts.Cfg)
	if err != nil {
		t.Fatalf("failed to configure metadata service: %v", err)
	}
	ts.MDS = mds

	const volName = "test"
	if err := block.CreateBlockVolume(mds, volName, 1024); err != nil {
		t.Fatalf("failed to create block volume: %v", err)
	}

	vol, err := block.OpenBlockVolume(ts, volName)
	if err != nil {
		t.Fatalf("error opening block volume: %v", err)
	}

	as, err := NewServer(vol, nil)
	if err != nil {
		t.Fatalf("error opening AoE server: %v", err)
	}

	serverWrite := bytes.NewBuffer(nil)
	serverRead := bytes.NewBuffer(nil)

	bp := &bufPacketConn{
		rb: serverWrite,
		wb: serverRead,
	}

	iface := &Interface{
		Interface: &net.Interface{
			Name: "lo",
			MTU:  testMTU,
		},
		PacketConn: bp,
	}

	run = func() error {
		if err := as.Serve(iface); err != nil {
			return fmt.Errorf("failed to serve AoE: %v", err)
		}

		bp.mu.Lock()
		defer bp.mu.Unlock()

		if !bp.gotBroadcast {
			return errors.New("broadcast advertise was never received")
		}

		return nil
	}

	done = func() {
		_ = as.Close()
		_ = iface.PacketConn.Close()
		_ = ts.Close()
	}

	return serverRead, serverWrite, run, done
}
Beispiel #12
0
func blockLoadAction(cmd *cobra.Command, args []string) error {
	if len(args) != 2 && len(args) != 3 {
		return torus.ErrUsage
	}
	input, err := getReaderFromArg(args[0])
	if err != nil {
		return fmt.Errorf("couldn't open input: %v", err)
	}
	srv := createServer()
	defer srv.Close()
	fi, err := input.Stat()
	if err != nil {
		return fmt.Errorf("couldn't stat input file: %v", err)
	}

	size := uint64(fi.Size())
	if len(args) == 3 {
		expSize, err := humanize.ParseBytes(args[2])
		if err != nil {
			return fmt.Errorf("error parsing size %s: %v", args[2], err)
		}

		if expSize < size {
			return fmt.Errorf("size must be larger than input file")
		}

		size = expSize
	}

	err = block.CreateBlockVolume(srv.MDS, args[1], size)
	if err != nil {
		return fmt.Errorf("couldn't create block volume %s: %v", args[1], err)
	}
	blockvol, err := block.OpenBlockVolume(srv, args[1])
	if err != nil {
		return fmt.Errorf("couldn't open block volume %s: %v", args[1], err)
	}
	f, err := blockvol.OpenBlockFile()
	if err != nil {
		return fmt.Errorf("couldn't open blockfile %s: %v", args[1], err)
	}
	defer f.Close()

	if progress {
		pb := progressutil.NewCopyProgressPrinter()
		pb.AddCopy(input, path.Base(args[0]), fi.Size(), f)
		err := pb.PrintAndWait(os.Stderr, 500*time.Millisecond, nil)
		if err != nil {
			return fmt.Errorf("couldn't copy: %v", err)
		}
	} else {
		_, err := io.Copy(f, input)
		if err != nil {
			return fmt.Errorf("couldn't copy: %v", err)
		}
	}

	err = f.Sync()
	if err != nil {
		return fmt.Errorf("couldn't sync: %v", err)
	}
	fmt.Printf("copied %d bytes\n", fi.Size())
	return nil
}
func aoeAction(cmd *cobra.Command, args []string) {
	if len(args) != 4 {
		cmd.Usage()
		os.Exit(1)
	}

	srv := createServer()

	vol := args[0]
	ifname := args[1]
	maj := args[2]
	min := args[3]

	major, err := strconv.ParseUint(maj, 10, 16)
	if err != nil {
		die("Failed to parse major address %q: %v\n", maj, err)
	}

	minor, err := strconv.ParseUint(min, 10, 8)
	if err != nil {
		die("Failed to parse minor address %q: %v\n", min, err)
	}

	blockvol, err := block.OpenBlockVolume(srv, vol)
	if err != nil {
		fmt.Println("server doesn't support block volumes:", err)
		os.Exit(1)
	}

	ai, err := aoe.NewInterface(ifname)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to set up interface %q: %v\n", ifname, err)
		os.Exit(1)
	}

	as, err := aoe.NewServer(blockvol, &aoe.ServerOptions{
		Major: uint16(major),
		Minor: uint8(minor),
	})
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to crate AoE server: %v\n", err)
		os.Exit(1)
	}

	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, os.Interrupt)

	go func(sv *torus.Server, iface *aoe.Interface) {
		for _ = range signalChan {
			fmt.Println("\nReceived an interrupt, stopping services...")

			iface.Close()
			sv.Close()
			as.Close()
			os.Exit(0)
		}
	}(srv, ai)

	if err = as.Serve(ai); err != nil {
		fmt.Fprintf(os.Stderr, "Failed to serve AoE: %v\n", err)
		os.Exit(1)
	}
}
Beispiel #14
0
func aoeAction(cmd *cobra.Command, args []string) error {
	if len(aoeFlush) > 0 && len(args) == 0 {
		if err := flush(aoeFlush); err != nil {
			return fmt.Errorf("failed to flush: %v", err)
		}
		return nil
	}

	if len(args) != 4 {
		return torus.ErrUsage
	}

	srv := createServer()
	defer srv.Close()

	vol := args[0]
	ifname := args[1]
	maj := args[2]
	min := args[3]

	major, err := strconv.ParseUint(maj, 10, 16)
	if err != nil {
		return fmt.Errorf("Failed to parse major address %q: %v", maj, err)
	}

	minor, err := strconv.ParseUint(min, 10, 8)
	if err != nil {
		return fmt.Errorf("Failed to parse minor address %q: %v", min, err)
	}

	blockvol, err := block.OpenBlockVolume(srv, vol)
	if err != nil {
		return fmt.Errorf("server doesn't support block volumes: %v", err)
	}

	ai, err := aoe.NewInterface(ifname)
	if err != nil {
		return fmt.Errorf("Failed to set up interface %q: %v", ifname, err)
	}

	as, err := aoe.NewServer(blockvol, &aoe.ServerOptions{
		Major: uint16(major),
		Minor: uint8(minor),
	})
	if err != nil {
		return fmt.Errorf("Failed to crate AoE server: %v", err)
	}
	defer as.Close()

	signalChan := make(chan os.Signal, 1)
	signal.Notify(signalChan, os.Interrupt)

	go func(iface *aoe.Interface) {
		for _ = range signalChan {
			fmt.Println("\nReceived an interrupt, stopping services...")
			iface.Close()
		}
	}(ai)

	if err = as.Serve(ai); err != nil {
		return fmt.Errorf("Failed to serve AoE: %v", err)
	}
	return nil
}