Merge "Update IPC benchmark results with Go 1.4."
diff --git a/lib/testutil/integration/util.go b/lib/testutil/integration/util.go
index b535576..fdc0afa 100644
--- a/lib/testutil/integration/util.go
+++ b/lib/testutil/integration/util.go
@@ -2,20 +2,317 @@
 
 import (
 	"bufio"
+	"bytes"
 	"fmt"
+	"io"
 	"io/ioutil"
 	"os"
 	"os/exec"
 	"path"
 	"path/filepath"
 	"strings"
+	"syscall"
+	"testing"
 	"time"
 
 	"veyron.io/veyron/veyron/lib/expect"
 	"veyron.io/veyron/veyron/lib/modules"
 	"veyron.io/veyron/veyron/lib/modules/core"
+	tsecurity "veyron.io/veyron/veyron/lib/testutil/security"
+	"veyron.io/veyron/veyron2/security"
 )
 
+// TestEnvironment represents a test environment. You should obtain
+// an instance with NewTestEnvironment. Typically, an end-to-end
+// test will begin with:
+//   func TestFoo(t *testing.T) {
+//     env := integration.NewTestEnvironment(t)
+//     defer env.Cleanup()
+//
+//     ...
+//   }
+type TestEnvironment interface {
+	// Cleanup cleans up the environment and deletes all its artifacts.
+	Cleanup()
+
+	// BuildGoPkg expects a Go package path that identifies a "main"
+	// package and returns a TestBinary representing the newly built
+	// binary.
+	BuildGoPkg(path string) TestBinary
+
+	// RootMT returns the endpoint to the root mounttable for this test
+	// environment.
+	RootMT() string
+
+	// Principal returns the security principal of this environment.
+	Principal() security.Principal
+
+	// DebugShell drops the user into a debug shell. If there is no
+	// controlling TTY, DebugShell will emit a warning message and take no
+	// futher action.
+	DebugShell()
+
+	// TempFile creates a temporary file. Temporary files will be deleted
+	// by Cleanup.
+	TempFile() *os.File
+}
+
+type TestBinary interface {
+	// Start starts the given binary with the given arguments.
+	Start(args ...string) Invocation
+
+	// Path returns the path to the binary.
+	Path() string
+}
+
+type Invocation interface {
+	Stdin() io.Writer
+	Stdout() io.Reader
+	Stderr() io.Reader
+
+	// Output reads the invocation's stdout until EOF and then returns what
+	// was read as a string.
+	Output() string
+
+	// ErrorOutput reads the invocation's stderr until EOF and then returns
+	// what was read as a string.
+	ErrorOutput() string
+
+	// Wait waits for this invocation to finish. If either stdout or stderr
+	// is non-nil, any remaining unread output from those sources will be
+	// written to the corresponding writer.
+	Wait(stdout, stderr io.Writer)
+}
+
+type integrationTestEnvironment struct {
+	// The testing framework.
+	t *testing.T
+
+	// The shell to use to start commands.
+	shell *modules.Shell
+
+	// The environment's root security principal.
+	principal security.Principal
+
+	// Maps path to TestBinary.
+	builtBinaries map[string]*integrationTestBinary
+
+	mtHandle   *modules.Handle
+	mtEndpoint string
+
+	tempFiles []*os.File
+}
+
+type integrationTestBinary struct {
+	// The environment to which this binary belongs.
+	env *integrationTestEnvironment
+
+	// The path to the binary.
+	path string
+
+	// The cleanup function to run when the binary exits.
+	cleanupFunc func()
+}
+
+type integrationTestBinaryInvocation struct {
+	// The environment to which this invocation belongs.
+	env *integrationTestEnvironment
+
+	// The handle to the process that was run when this invocation was started.
+	handle *modules.Handle
+}
+
+func (i *integrationTestBinaryInvocation) Stdin() io.Writer {
+	return (*i.handle).Stdin()
+}
+
+func (i *integrationTestBinaryInvocation) Stdout() io.Reader {
+	return (*i.handle).Stdout()
+}
+
+func readerToString(t *testing.T, r io.Reader) string {
+	buf := bytes.Buffer{}
+	_, err := buf.ReadFrom(r)
+	if err != nil {
+		t.Fatalf("ReadFrom() failed: %v", err)
+	}
+	return buf.String()
+}
+
+func (i *integrationTestBinaryInvocation) Output() string {
+	return readerToString(i.env.t, i.Stdout())
+}
+
+func (i *integrationTestBinaryInvocation) Stderr() io.Reader {
+	return (*i.handle).Stderr()
+}
+
+func (i *integrationTestBinaryInvocation) ErrorOutput() string {
+	return readerToString(i.env.t, i.Stderr())
+}
+
+func (i *integrationTestBinaryInvocation) Wait(stdout, stderr io.Writer) {
+	if err := (*i.handle).Shutdown(stdout, stderr); err != nil {
+		i.env.t.Fatalf("Shutdown() failed: %v", err)
+	}
+}
+
+func (b *integrationTestBinary) cleanup() {
+	binaryDir := path.Dir(b.path)
+	b.env.t.Logf("cleaning up %s", binaryDir)
+	if err := os.RemoveAll(binaryDir); err != nil {
+		b.env.t.Logf("WARNING: RemoveAll(%s) failed (%v)", binaryDir, err)
+	}
+}
+
+func (b *integrationTestBinary) Path() string {
+	return b.path
+}
+
+func (b *integrationTestBinary) Start(args ...string) Invocation {
+	b.env.t.Logf("starting %s %s", b.Path(), strings.Join(args, " "))
+	handle, err := b.env.shell.Start("exec", nil, append([]string{b.Path()}, args...)...)
+	if err != nil {
+		b.env.t.Fatalf("Start(%v, %v) failed: %v", b.Path(), strings.Join(args, ", "), err)
+	}
+	return &integrationTestBinaryInvocation{
+		env:    b.env,
+		handle: &handle,
+	}
+}
+
+func (e *integrationTestEnvironment) RootMT() string {
+	return e.mtEndpoint
+}
+
+func (e *integrationTestEnvironment) Principal() security.Principal {
+	return e.principal
+}
+
+func (e *integrationTestEnvironment) Cleanup() {
+	for _, binary := range e.builtBinaries {
+		binary.cleanupFunc()
+	}
+
+	for _, tempFile := range e.tempFiles {
+		e.t.Logf("cleaning up %s", tempFile.Name())
+		if err := tempFile.Close(); err != nil {
+			e.t.Logf("WARNING: Close(%s) failed", tempFile, err)
+		}
+		if err := os.Remove(tempFile.Name()); err != nil {
+			e.t.Logf("WARNING: Remove(%s) failed: %v", tempFile.Name(), err)
+		}
+	}
+
+	if err := e.shell.Cleanup(os.Stdout, os.Stderr); err != nil {
+		e.t.Fatalf("WARNING: could not clean up shell (%v)", err)
+	}
+}
+
+func (e *integrationTestEnvironment) DebugShell() {
+	// Get the current working directory.
+	cwd, err := os.Getwd()
+	if err != nil {
+		e.t.Fatalf("Getwd() failed: %v", err)
+	}
+
+	// Transfer stdin, stdout, and stderr to the new process
+	// and also set target directory for the shell to start in.
+	dev := "/dev/tty"
+	fd, err := syscall.Open(dev, 0, 0)
+	if err != nil {
+		e.t.Logf("WARNING: Open(%v) failed, not going to create a debug shell: %v", dev, err)
+		return
+	}
+	attr := os.ProcAttr{
+		Files: []*os.File{os.NewFile(uintptr(fd), "/dev/tty"), os.Stdout, os.Stderr},
+		Dir:   cwd,
+	}
+
+	// Start up a new shell.
+	fmt.Printf(">> Starting a new interactive shell\n")
+	fmt.Printf("Hit CTRL-D to resume the test\n")
+	if len(e.builtBinaries) > 0 {
+		fmt.Println("Built binaries:")
+		for _, value := range e.builtBinaries {
+			fmt.Println(value.Path())
+		}
+	}
+	fmt.Println("Root mounttable endpoint:", e.RootMT())
+
+	shellPath := "/bin/sh"
+	proc, err := os.StartProcess(shellPath, []string{}, &attr)
+	if err != nil {
+		e.t.Fatalf("StartProcess(%v) failed: %v", shellPath, err)
+	}
+
+	// Wait until user exits the shell
+	state, err := proc.Wait()
+	if err != nil {
+		e.t.Fatalf("Wait(%v) failed: %v", shellPath, err)
+	}
+
+	fmt.Printf("<< Exited shell: %s\n", state.String())
+}
+
+func (e *integrationTestEnvironment) BuildGoPkg(binary_path string) TestBinary {
+	e.t.Logf("building %s...", binary_path)
+	if cached_binary := e.builtBinaries[binary_path]; cached_binary != nil {
+		e.t.Logf("using cached binary for %s at %s.", binary_path, cached_binary.Path())
+		return cached_binary
+	}
+	built_path, cleanup, err := BuildPkgs([]string{binary_path})
+	if err != nil {
+		e.t.Fatalf("BuildPkgs() failed: %v", err)
+		return nil
+	}
+	output_path := path.Join(built_path, path.Base(binary_path))
+	e.t.Logf("done building %s, written to %s.", binary_path, output_path)
+	binary := &integrationTestBinary{
+		env:         e,
+		path:        output_path,
+		cleanupFunc: cleanup,
+	}
+	e.builtBinaries[binary_path] = binary
+	return binary
+}
+
+func (e *integrationTestEnvironment) TempFile() *os.File {
+	f, err := ioutil.TempFile("", "")
+	if err != nil {
+		e.t.Fatalf("TempFile() failed: %v", err)
+	}
+	e.t.Logf("created temporary file at %s", f.Name())
+	e.tempFiles = append(e.tempFiles, f)
+	return f
+}
+
+func NewTestEnvironment(t *testing.T) TestEnvironment {
+	t.Log("creating root principal")
+	principal := tsecurity.NewPrincipal("root")
+	shell, err := modules.NewShell(principal)
+	if err != nil {
+		t.Fatalf("NewShell() failed: %v", err)
+	}
+
+	t.Log("starting root mounttable...")
+	mtHandle, mtEndpoint, err := StartRootMT(shell)
+	if err != nil {
+		t.Fatalf("StartRootMT() failed: %v", err)
+	}
+	t.Logf("mounttable available at %s", mtEndpoint)
+
+	return &integrationTestEnvironment{
+		t:             t,
+		principal:     principal,
+		builtBinaries: make(map[string]*integrationTestBinary),
+		shell:         shell,
+		mtHandle:      &mtHandle,
+		mtEndpoint:    mtEndpoint,
+		tempFiles:     []*os.File{},
+	}
+}
+
 // BuildPkgs returns a path to a directory that contains the built
 // binaries for the given set of packages and a function that should
 // be invoked to clean up the build artifacts. Note that the clients
@@ -61,7 +358,7 @@
 	if err != nil {
 		return nil, "", err
 	}
-	s := expect.NewSession(nil, handle.Stdout(), time.Second)
+	s := expect.NewSession(nil, handle.Stdout(), 10*time.Second)
 	s.ExpectVar("PID")
 	if err := s.Error(); err != nil {
 		return nil, "", err
diff --git a/security/principal.go b/security/principal.go
index 4ebf6e6..304c4d1 100644
--- a/security/principal.go
+++ b/security/principal.go
@@ -114,23 +114,31 @@
 	return NewPrincipalFromSigner(security.NewInMemoryECDSASigner(key), state)
 }
 
+// SetDefaultBlessings sets the provided blessings as default and shareable with
+// all peers on provided principal's BlessingStore, and also adds it as a root to
+// the principal's BlessingRoots.
+func SetDefaultBlessings(p security.Principal, blessings security.Blessings) error {
+	if err := p.BlessingStore().SetDefault(blessings); err != nil {
+		return err
+	}
+	if _, err := p.BlessingStore().Set(blessings, security.AllPrincipals); err != nil {
+		return err
+	}
+	if err := p.AddToRoots(blessings); err != nil {
+		return err
+	}
+	return nil
+}
+
 // InitDefaultBlessings uses the provided principal to create a self blessing for name 'name',
 // sets it as default on the principal's BlessingStore and adds it as root to the principal's BlessingRoots.
+// TODO(ataly): Get rid this function given that we have SetDefaultBlessings.
 func InitDefaultBlessings(p security.Principal, name string) error {
 	blessing, err := p.BlessSelf(name)
 	if err != nil {
 		return err
 	}
-	if err := p.BlessingStore().SetDefault(blessing); err != nil {
-		return err
-	}
-	if _, err := p.BlessingStore().Set(blessing, security.AllPrincipals); err != nil {
-		return err
-	}
-	if err := p.AddToRoots(blessing); err != nil {
-		return err
-	}
-	return nil
+	return SetDefaultBlessings(p, blessing)
 }
 
 func mkDir(dir string) error {
diff --git a/services/mgmt/binary/impl/fs_utils.go b/services/mgmt/binary/impl/fs_utils.go
index 3240d31..d87fd9b 100644
--- a/services/mgmt/binary/impl/fs_utils.go
+++ b/services/mgmt/binary/impl/fs_utils.go
@@ -8,6 +8,7 @@
 	"strconv"
 	"strings"
 
+	verror "veyron.io/veyron/veyron2/verror2"
 	"veyron.io/veyron/veyron2/vlog"
 )
 
@@ -25,19 +26,19 @@
 func checksumExists(path string) error {
 	switch _, err := os.Stat(path); {
 	case os.IsNotExist(err):
-		return errInvalidPart
+		return verror.Make(errInvalidPart, nil, path)
 	case err != nil:
 		vlog.Errorf("Stat(%v) failed: %v", path, err)
-		return errOperationFailed
+		return verror.Make(errOperationFailed, nil, path)
 	}
 	checksumFile := filepath.Join(path, checksum)
 	_, err := os.Stat(checksumFile)
 	switch {
 	case os.IsNotExist(err):
-		return errNotFound
+		return verror.Make(verror.NoExist, nil, path)
 	case err != nil:
 		vlog.Errorf("Stat(%v) failed: %v", checksumFile, err)
-		return errOperationFailed
+		return verror.Make(errOperationFailed, nil, path)
 	default:
 		return nil
 	}
@@ -57,7 +58,7 @@
 	infos, err := ioutil.ReadDir(path)
 	if err != nil {
 		vlog.Errorf("ReadDir(%v) failed: %v", path, err)
-		return []string{}, errOperationFailed
+		return []string{}, verror.Make(errOperationFailed, nil, path)
 	}
 	nDirs := 0
 	for _, info := range infos {
@@ -72,10 +73,10 @@
 			idx, err := strconv.Atoi(partName)
 			if err != nil {
 				vlog.Errorf("Atoi(%v) failed: %v", partName, err)
-				return []string{}, errOperationFailed
+				return []string{}, verror.Make(errOperationFailed, nil, path)
 			}
 			if idx < 0 || idx >= len(infos) || result[idx] != "" {
-				return []string{}, errOperationFailed
+				return []string{}, verror.Make(errOperationFailed, nil, path)
 			}
 			result[idx] = filepath.Join(path, partName)
 		} else {
@@ -83,7 +84,7 @@
 				continue
 			}
 			// The only entries should correspond to the part dirs.
-			return []string{}, errOperationFailed
+			return []string{}, verror.Make(errOperationFailed, nil, path)
 		}
 	}
 	return result, nil
diff --git a/services/mgmt/binary/impl/http.go b/services/mgmt/binary/impl/http.go
index 251ff00..1242bd2 100644
--- a/services/mgmt/binary/impl/http.go
+++ b/services/mgmt/binary/impl/http.go
@@ -6,6 +6,7 @@
 	"path/filepath"
 	"strings"
 
+	verror "veyron.io/veyron/veyron2/verror2"
 	"veyron.io/veyron/veyron2/vlog"
 
 	"veyron.io/veyron/veyron/services/mgmt/binary/impl/multipart"
@@ -42,7 +43,7 @@
 		var err error
 		if partFiles[i], err = os.Open(dataPath); err != nil {
 			vlog.Errorf("Open(%v) failed: %v", dataPath, err)
-			return nil, errOperationFailed
+			return nil, verror.Make(errOperationFailed, nil, dataPath)
 		}
 	}
 	return multipart.NewFile(name, partFiles)
diff --git a/services/mgmt/binary/impl/impl_test.go b/services/mgmt/binary/impl/impl_test.go
index a34937f..0f1f1ee 100644
--- a/services/mgmt/binary/impl/impl_test.go
+++ b/services/mgmt/binary/impl/impl_test.go
@@ -17,7 +17,7 @@
 	"veyron.io/veyron/veyron2/naming"
 	"veyron.io/veyron/veyron2/rt"
 	"veyron.io/veyron/veyron2/services/mgmt/repository"
-	"veyron.io/veyron/veyron2/verror"
+	verror "veyron.io/veyron/veyron2/verror2"
 	"veyron.io/veyron/veyron2/vlog"
 
 	"veyron.io/veyron/veyron/lib/testutil"
@@ -320,7 +320,7 @@
 	}
 	if err := binary.Create(runtime.NewContext(), int32(length), repository.MediaInfo{Type: "application/octet-stream"}); err == nil {
 		t.Fatalf("Create() did not fail when it should have")
-	} else if want := verror.Exists; !verror.Is(err, want) {
+	} else if want := verror.Exist.ID; !verror.Is(err, want) {
 		t.Fatalf("Unexpected error: %v, expected error id %v", err, want)
 	}
 	if streamErr, err := invokeUpload(t, binary, data[0], 0); streamErr != nil || err != nil {
@@ -328,12 +328,12 @@
 	}
 	if _, err := invokeUpload(t, binary, data[0], 0); err == nil {
 		t.Fatalf("Upload() did not fail when it should have")
-	} else if want := verror.Exists; !verror.Is(err, want) {
+	} else if want := verror.Exist.ID; !verror.Is(err, want) {
 		t.Fatalf("Unexpected error: %v, expected error id %v", err, want)
 	}
 	if _, _, err := invokeDownload(t, binary, 1); err == nil {
 		t.Fatalf("Download() did not fail when it should have")
-	} else if want := verror.NoExist; !verror.Is(err, want) {
+	} else if want := verror.NoExist.ID; !verror.Is(err, want) {
 		t.Fatalf("Unexpected error: %v, expected error id %v", err, want)
 	}
 	if streamErr, err := invokeUpload(t, binary, data[1], 1); streamErr != nil || err != nil {
@@ -347,12 +347,12 @@
 	for _, part := range []int32{-1, length} {
 		if _, err := invokeUpload(t, binary, []byte("dummy"), part); err == nil {
 			t.Fatalf("Upload() did not fail when it should have")
-		} else if want := verror.BadArg; !verror.Is(err, want) {
+		} else if want := errInvalidPart.ID; !verror.Is(err, want) {
 			t.Fatalf("Unexpected error: %v, expected error id %v", err, want)
 		}
 		if _, _, err := invokeDownload(t, binary, part); err == nil {
 			t.Fatalf("Download() did not fail when it should have")
-		} else if want := verror.BadArg; !verror.Is(err, want) {
+		} else if want := errInvalidPart.ID; !verror.Is(err, want) {
 			t.Fatalf("Unexpected error: %v, expected error id %v", err, want)
 		}
 	}
@@ -361,7 +361,7 @@
 	}
 	if err := binary.Delete(runtime.NewContext()); err == nil {
 		t.Fatalf("Delete() did not fail when it should have")
-	} else if want := verror.NoExist; !verror.Is(err, want) {
+	} else if want := verror.NoExist.ID; !verror.Is(err, want) {
 		t.Fatalf("Unexpected error: %v, expected error id %v", err, want)
 	}
 }
diff --git a/services/mgmt/binary/impl/service.go b/services/mgmt/binary/impl/service.go
index 6249891..e7cfc9d 100644
--- a/services/mgmt/binary/impl/service.go
+++ b/services/mgmt/binary/impl/service.go
@@ -34,7 +34,7 @@
 	"veyron.io/veyron/veyron2/ipc"
 	"veyron.io/veyron/veyron2/services/mgmt/binary"
 	"veyron.io/veyron/veyron2/services/mgmt/repository"
-	"veyron.io/veyron/veyron2/verror"
+	verror "veyron.io/veyron/veyron2/verror2"
 	"veyron.io/veyron/veyron2/vlog"
 )
 
@@ -50,13 +50,13 @@
 	suffix string
 }
 
+const pkgPath = "veyron.io/veyron/veyron/services/mgmt/binary/impl"
+
 var (
-	errExists          = verror.Existsf("binary already exists")
-	errNotFound        = verror.NoExistf("binary not found")
-	errInProgress      = verror.Internalf("identical upload already in progress")
-	errInvalidParts    = verror.BadArgf("invalid number of binary parts")
-	errInvalidPart     = verror.BadArgf("invalid binary part number")
-	errOperationFailed = verror.Internalf("operation failed")
+	errInProgress      = verror.Register(pkgPath+".errInProgress", verror.NoRetry, "{1:}{2:} identical upload already in progress{:_}")
+	errInvalidParts    = verror.Register(pkgPath+".errInvalidParts", verror.NoRetry, "{1:}{2:} invalid number of binary parts{:_}")
+	errInvalidPart     = verror.Register(pkgPath+".errInvalidPart", verror.NoRetry, "{1:}{2:} invalid binary part number{:_}")
+	errOperationFailed = verror.Register(pkgPath+".errOperationFailed", verror.NoRetry, "{1:}{2:} operation failed{:_}")
 )
 
 // TODO(jsimsa): When VDL supports composite literal constants, remove
@@ -77,36 +77,36 @@
 
 const bufferLength = 4096
 
-func (i *binaryService) Create(_ ipc.ServerContext, nparts int32, mediaInfo repository.MediaInfo) error {
+func (i *binaryService) Create(context ipc.ServerContext, nparts int32, mediaInfo repository.MediaInfo) error {
 	vlog.Infof("%v.Create(%v, %v)", i.suffix, nparts, mediaInfo)
 	if nparts < 1 {
-		return errInvalidParts
+		return verror.Make(errInvalidParts, context)
 	}
 	parent, perm := filepath.Dir(i.path), os.FileMode(0700)
 	if err := os.MkdirAll(parent, perm); err != nil {
 		vlog.Errorf("MkdirAll(%v, %v) failed: %v", parent, perm, err)
-		return errOperationFailed
+		return verror.Make(errOperationFailed, context)
 	}
 	prefix := "creating-"
 	tmpDir, err := ioutil.TempDir(parent, prefix)
 	if err != nil {
 		vlog.Errorf("TempDir(%v, %v) failed: %v", parent, prefix, err)
-		return errOperationFailed
+		return verror.Make(errOperationFailed, context)
 	}
 	nameFile := filepath.Join(tmpDir, "name")
 	if err := ioutil.WriteFile(nameFile, []byte(i.suffix), os.FileMode(0600)); err != nil {
 		vlog.Errorf("WriteFile(%q) failed: %v", nameFile)
-		return errOperationFailed
+		return verror.Make(errOperationFailed, context)
 	}
 	infoFile := filepath.Join(tmpDir, "mediainfo")
 	jInfo, err := json.Marshal(mediaInfo)
 	if err != nil {
 		vlog.Errorf("json.Marshal(%v) failed: %v", mediaInfo, err)
-		return errOperationFailed
+		return verror.Make(errOperationFailed, context)
 	}
 	if err := ioutil.WriteFile(infoFile, jInfo, os.FileMode(0600)); err != nil {
 		vlog.Errorf("WriteFile(%q) failed: %v", infoFile, err)
-		return errOperationFailed
+		return verror.Make(errOperationFailed, context)
 	}
 	for j := 0; j < int(nparts); j++ {
 		partPath, partPerm := generatePartPath(tmpDir, j), os.FileMode(0700)
@@ -115,7 +115,7 @@
 			if err := os.RemoveAll(tmpDir); err != nil {
 				vlog.Errorf("RemoveAll(%v) failed: %v", tmpDir, err)
 			}
-			return errOperationFailed
+			return verror.Make(errOperationFailed, context)
 		}
 	}
 	// Use os.Rename() to atomically create the binary directory
@@ -127,10 +127,10 @@
 			}
 		}()
 		if linkErr, ok := err.(*os.LinkError); ok && linkErr.Err == syscall.ENOTEMPTY {
-			return errExists
+			return verror.Make(verror.Exist, context, i.path)
 		}
 		vlog.Errorf("Rename(%v, %v) failed: %v", tmpDir, i.path, err)
-		return errOperationFailed
+		return verror.Make(errOperationFailed, context, i.path)
 	}
 	return nil
 }
@@ -139,21 +139,21 @@
 	vlog.Infof("%v.Delete()", i.suffix)
 	if _, err := os.Stat(i.path); err != nil {
 		if os.IsNotExist(err) {
-			return errNotFound
+			return verror.Make(verror.NoExist, context, i.path)
 		}
 		vlog.Errorf("Stat(%v) failed: %v", i.path, err)
-		return errOperationFailed
+		return verror.Make(errOperationFailed, context)
 	}
 	// Use os.Rename() to atomically remove the binary directory
 	// structure.
 	path := filepath.Join(filepath.Dir(i.path), "removing-"+filepath.Base(i.path))
 	if err := os.Rename(i.path, path); err != nil {
 		vlog.Errorf("Rename(%v, %v) failed: %v", i.path, path, err)
-		return errOperationFailed
+		return verror.Make(errOperationFailed, context, i.path)
 	}
 	if err := os.RemoveAll(path); err != nil {
 		vlog.Errorf("Remove(%v) failed: %v", path, err)
-		return errOperationFailed
+		return verror.Make(errOperationFailed, context)
 	}
 	for {
 		// Remove the binary and all directories on the path back to the
@@ -167,7 +167,7 @@
 				break
 			}
 			vlog.Errorf("Remove(%v) failed: %v", path, err)
-			return errOperationFailed
+			return verror.Make(errOperationFailed, context)
 		}
 	}
 	return nil
@@ -183,7 +183,7 @@
 	file, err := os.Open(dataPath)
 	if err != nil {
 		vlog.Errorf("Open(%v) failed: %v", dataPath, err)
-		return errOperationFailed
+		return verror.Make(errOperationFailed, context)
 	}
 	defer file.Close()
 	buffer := make([]byte, bufferLength)
@@ -192,14 +192,14 @@
 		n, err := file.Read(buffer)
 		if err != nil && err != io.EOF {
 			vlog.Errorf("Read() failed: %v", err)
-			return errOperationFailed
+			return verror.Make(errOperationFailed, context)
 		}
 		if n == 0 {
 			break
 		}
 		if err := sender.Send(buffer[:n]); err != nil {
 			vlog.Errorf("Send() failed: %v", err)
-			return errOperationFailed
+			return verror.Make(errOperationFailed, context)
 		}
 	}
 	return nil
@@ -212,7 +212,7 @@
 	return i.state.rootURL + "/" + i.suffix, 0, nil
 }
 
-func (i *binaryService) Stat(ipc.ServerContext) ([]binary.PartInfo, repository.MediaInfo, error) {
+func (i *binaryService) Stat(context ipc.ServerContext) ([]binary.PartInfo, repository.MediaInfo, error) {
 	vlog.Infof("%v.Stat()", i.suffix)
 	result := make([]binary.PartInfo, 0)
 	parts, err := getParts(i.path)
@@ -228,7 +228,7 @@
 				continue
 			}
 			vlog.Errorf("ReadFile(%v) failed: %v", checksumFile, err)
-			return []binary.PartInfo{}, repository.MediaInfo{}, errOperationFailed
+			return []binary.PartInfo{}, repository.MediaInfo{}, verror.Make(errOperationFailed, context)
 		}
 		dataFile := filepath.Join(part, data)
 		fi, err := os.Stat(dataFile)
@@ -238,7 +238,7 @@
 				continue
 			}
 			vlog.Errorf("Stat(%v) failed: %v", dataFile, err)
-			return []binary.PartInfo{}, repository.MediaInfo{}, errOperationFailed
+			return []binary.PartInfo{}, repository.MediaInfo{}, verror.Make(errOperationFailed, context)
 		}
 		result = append(result, binary.PartInfo{Checksum: string(bytes), Size: fi.Size()})
 	}
@@ -246,12 +246,12 @@
 	jInfo, err := ioutil.ReadFile(infoFile)
 	if err != nil {
 		vlog.Errorf("ReadFile(%q) failed: %v", infoFile)
-		return []binary.PartInfo{}, repository.MediaInfo{}, errOperationFailed
+		return []binary.PartInfo{}, repository.MediaInfo{}, verror.Make(errOperationFailed, context)
 	}
 	var mediaInfo repository.MediaInfo
 	if err := json.Unmarshal(jInfo, &mediaInfo); err != nil {
 		vlog.Errorf("json.Unmarshal(%v) failed: %v", jInfo, err)
-		return []binary.PartInfo{}, repository.MediaInfo{}, errOperationFailed
+		return []binary.PartInfo{}, repository.MediaInfo{}, verror.Make(errOperationFailed, context)
 	}
 	return result, mediaInfo, nil
 }
@@ -260,11 +260,9 @@
 	vlog.Infof("%v.Upload(%v)", i.suffix, part)
 	path, suffix := i.generatePartPath(int(part)), ""
 	err := checksumExists(path)
-	switch err {
-	case nil:
-		return errExists
-	case errNotFound:
-	default:
+	if err == nil {
+		return verror.Make(verror.Exist, context, path)
+	} else if !verror.Is(err, verror.NoExist.ID) {
 		return err
 	}
 	// Use os.OpenFile() to resolve races.
@@ -272,17 +270,17 @@
 	lockFile, err := os.OpenFile(lockPath, flags, perm)
 	if err != nil {
 		if os.IsExist(err) {
-			return errInProgress
+			return verror.Make(errInProgress, context, path)
 		}
 		vlog.Errorf("OpenFile(%v, %v, %v) failed: %v", lockPath, flags, suffix, err)
-		return errOperationFailed
+		return verror.Make(errOperationFailed, context)
 	}
 	defer os.Remove(lockFile.Name())
 	defer lockFile.Close()
 	file, err := ioutil.TempFile(path, suffix)
 	if err != nil {
 		vlog.Errorf("TempFile(%v, %v) failed: %v", path, suffix, err)
-		return errOperationFailed
+		return verror.Make(errOperationFailed, context)
 	}
 	defer file.Close()
 	h := md5.New()
@@ -294,7 +292,7 @@
 			if err := os.Remove(file.Name()); err != nil {
 				vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
 			}
-			return errOperationFailed
+			return verror.Make(errOperationFailed, context)
 		}
 		h.Write(bytes)
 	}
@@ -304,7 +302,7 @@
 		if err := os.Remove(file.Name()); err != nil {
 			vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
 		}
-		return errOperationFailed
+		return verror.Make(errOperationFailed, context)
 	}
 
 	hash := hex.EncodeToString(h.Sum(nil))
@@ -314,7 +312,7 @@
 		if err := os.Remove(file.Name()); err != nil {
 			vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
 		}
-		return errOperationFailed
+		return verror.Make(errOperationFailed, context)
 	}
 	dataFile := filepath.Join(path, data)
 	if err := os.Rename(file.Name(), dataFile); err != nil {
@@ -322,19 +320,19 @@
 		if err := os.Remove(file.Name()); err != nil {
 			vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
 		}
-		return errOperationFailed
+		return verror.Make(errOperationFailed, context)
 	}
 	return nil
 }
 
-func (i *binaryService) GlobChildren__(ipc.ServerContext) (<-chan string, error) {
+func (i *binaryService) GlobChildren__(context ipc.ServerContext) (<-chan string, error) {
 	elems := strings.Split(i.suffix, "/")
 	if len(elems) == 1 && elems[0] == "" {
 		elems = nil
 	}
 	n := i.createObjectNameTree().find(elems, false)
 	if n == nil {
-		return nil, errOperationFailed
+		return nil, verror.Make(errOperationFailed, context)
 	}
 	ch := make(chan string, 100)
 	go func() {
diff --git a/services/mgmt/build/impl/impl_test.go b/services/mgmt/build/impl/impl_test.go
index 4dfc78a..85b4773 100644
--- a/services/mgmt/build/impl/impl_test.go
+++ b/services/mgmt/build/impl/impl_test.go
@@ -48,7 +48,7 @@
 			t.Fatalf("LookPath(%q) failed: %v", name, err)
 		}
 	}
-	return pathbin, ""
+	return pathbin, os.Getenv("GOROOT")
 }
 
 // startServer starts the build server.
diff --git a/services/mgmt/build/impl/service.go b/services/mgmt/build/impl/service.go
index 83a93ef..59bec9f 100644
--- a/services/mgmt/build/impl/service.go
+++ b/services/mgmt/build/impl/service.go
@@ -12,13 +12,15 @@
 	"veyron.io/veyron/veyron2/ipc"
 	"veyron.io/veyron/veyron2/services/mgmt/binary"
 	"veyron.io/veyron/veyron2/services/mgmt/build"
-	"veyron.io/veyron/veyron2/verror"
+	verror "veyron.io/veyron/veyron2/verror2"
 	"veyron.io/veyron/veyron2/vlog"
 )
 
+const pkgPath = "veyron.io/veyron/veyron/services/mgmt/build/impl"
+
+// Errors
 var (
-	errBuildFailed   = verror.Internalf("build failed")
-	errInternalError = verror.Internalf("internal error")
+	errBuildFailed = verror.Register(pkgPath+".errBuildFailed", verror.NoRetry, "{1:}{2:} build failed{:_}")
 )
 
 // builderService implements the Builder server interface.
@@ -47,7 +49,7 @@
 	root, err := ioutil.TempDir(dir, prefix)
 	if err != nil {
 		vlog.Errorf("TempDir(%v, %v) failed: %v", dir, prefix, err)
-		return nil, errInternalError
+		return nil, verror.Make(verror.Internal, ctx)
 	}
 	defer os.RemoveAll(root)
 	if err := os.Chdir(root); err != nil {
@@ -56,7 +58,7 @@
 	srcDir := filepath.Join(root, "go", "src")
 	if err := os.MkdirAll(srcDir, dirPerm); err != nil {
 		vlog.Errorf("MkdirAll(%v, %v) failed: %v", srcDir, dirPerm, err)
-		return nil, errInternalError
+		return nil, verror.Make(verror.Internal, ctx)
 	}
 	iterator := ctx.RecvStream()
 	for iterator.Advance() {
@@ -65,16 +67,16 @@
 		dir := filepath.Dir(filePath)
 		if err := os.MkdirAll(dir, dirPerm); err != nil {
 			vlog.Errorf("MkdirAll(%v, %v) failed: %v", dir, dirPerm, err)
-			return nil, errInternalError
+			return nil, verror.Make(verror.Internal, ctx)
 		}
 		if err := ioutil.WriteFile(filePath, srcFile.Contents, filePerm); err != nil {
 			vlog.Errorf("WriteFile(%v, %v) failed: %v", filePath, filePerm, err)
-			return nil, errInternalError
+			return nil, verror.Make(verror.Internal, ctx)
 		}
 	}
 	if err := iterator.Err(); err != nil {
 		vlog.Errorf("Advance() failed: %v", err)
-		return nil, errInternalError
+		return nil, verror.Make(verror.Internal, ctx)
 	}
 	cmd := exec.Command(i.gobin, "install", "-v", "./...")
 	cmd.Env = append(cmd.Env, "GOARCH="+string(arch))
@@ -91,7 +93,7 @@
 		if output.Len() != 0 {
 			vlog.Errorf("%v", output.String())
 		}
-		return output.Bytes(), errBuildFailed
+		return output.Bytes(), verror.Make(errBuildFailed, ctx)
 	}
 	binDir := filepath.Join(root, "go", "bin")
 	if runtime.GOARCH != string(arch) || runtime.GOOS != string(opsys) {
@@ -100,14 +102,14 @@
 	files, err := ioutil.ReadDir(binDir)
 	if err != nil && !os.IsNotExist(err) {
 		vlog.Errorf("ReadDir(%v) failed: %v", binDir, err)
-		return nil, errInternalError
+		return nil, verror.Make(verror.Internal, ctx)
 	}
 	for _, file := range files {
 		binPath := filepath.Join(binDir, file.Name())
 		bytes, err := ioutil.ReadFile(binPath)
 		if err != nil {
 			vlog.Errorf("ReadFile(%v) failed: %v", binPath, err)
-			return nil, errInternalError
+			return nil, verror.Make(verror.Internal, ctx)
 		}
 		result := build.File{
 			Name:     "bin/" + file.Name(),
@@ -115,7 +117,7 @@
 		}
 		if err := ctx.SendStream().Send(result); err != nil {
 			vlog.Errorf("Send() failed: %v", err)
-			return nil, errInternalError
+			return nil, verror.Make(verror.Internal, ctx)
 		}
 	}
 	return output.Bytes(), nil
diff --git a/services/mgmt/debug/dispatcher_test.go b/services/mgmt/debug/dispatcher_test.go
index 4a65eaf..84ba35e 100644
--- a/services/mgmt/debug/dispatcher_test.go
+++ b/services/mgmt/debug/dispatcher_test.go
@@ -20,7 +20,7 @@
 	"veyron.io/veyron/veyron2/services/mgmt/logreader"
 	"veyron.io/veyron/veyron2/services/mgmt/stats"
 	vtracesvc "veyron.io/veyron/veyron2/services/mgmt/vtrace"
-	"veyron.io/veyron/veyron2/verror"
+	verror "veyron.io/veyron/veyron2/verror2"
 	"veyron.io/veyron/veyron2/vtrace"
 
 	libstats "veyron.io/veyron/veyron/lib/stats"
@@ -116,7 +116,7 @@
 	{
 		lf := logreader.LogFileClient(naming.JoinAddressName(endpoint, "debug/logs/nosuchfile.INFO"))
 		_, err = lf.Size(tracedContext())
-		if expected := verror.NoExist; !verror.Is(err, expected) {
+		if expected := verror.NoExist.ID; !verror.Is(err, expected) {
 			t.Errorf("unexpected error value, got %v, want: %v", err, expected)
 		}
 	}
@@ -140,7 +140,7 @@
 	{
 		st := stats.StatsClient(naming.JoinAddressName(endpoint, "debug/stats/testing/nobodyhome"))
 		_, err = st.Value(tracedContext())
-		if expected := verror.NoExist; !verror.Is(err, expected) {
+		if expected := verror.NoExist.ID; !verror.Is(err, expected) {
 			t.Errorf("unexpected error value, got %v, want: %v", err, expected)
 		}
 	}
diff --git a/services/mgmt/device/impl/app_service.go b/services/mgmt/device/impl/app_service.go
index bc37a2a..dc61c02 100644
--- a/services/mgmt/device/impl/app_service.go
+++ b/services/mgmt/device/impl/app_service.go
@@ -446,7 +446,7 @@
 	installationDir := filepath.Join(root, applicationDirName(app), installationDirName(installation))
 	if _, err := os.Stat(installationDir); err != nil {
 		if os.IsNotExist(err) {
-			return "", verror2.Make(ErrObjectNoExist, nil)
+			return "", verror2.Make(verror2.NoExist, nil, naming.Join(components...))
 		}
 		vlog.Errorf("Stat(%v) failed: %v", installationDir, err)
 		return "", verror2.Make(ErrOperationFailed, nil)
@@ -1220,7 +1220,7 @@
 		}
 		i.scanInstance(tree, i.suffix[0], dir)
 	default:
-		return nil, verror2.Make(ErrObjectNoExist, nil)
+		return nil, verror2.Make(verror2.NoExist, nil, i.suffix)
 	}
 	n := tree.find(i.suffix, false)
 	if n == nil {
diff --git a/services/mgmt/device/impl/dispatcher.go b/services/mgmt/device/impl/dispatcher.go
index 1e5bcbb..59bad06 100644
--- a/services/mgmt/device/impl/dispatcher.go
+++ b/services/mgmt/device/impl/dispatcher.go
@@ -27,8 +27,7 @@
 	"veyron.io/veyron/veyron2/services/mgmt/pprof"
 	"veyron.io/veyron/veyron2/services/mgmt/stats"
 	"veyron.io/veyron/veyron2/services/security/access"
-	"veyron.io/veyron/veyron2/verror"
-	"veyron.io/veyron/veyron2/verror2"
+	verror "veyron.io/veyron/veyron2/verror2"
 	"veyron.io/veyron/veyron2/vlog"
 )
 
@@ -77,14 +76,13 @@
 )
 
 var (
-	ErrInvalidSuffix       = verror2.Register(pkgPath+".InvalidSuffix", verror2.NoRetry, "")
-	ErrOperationFailed     = verror2.Register(pkgPath+".OperationFailed", verror2.NoRetry, "")
-	ErrOperationInProgress = verror2.Register(pkgPath+".OperationInProgress", verror2.NoRetry, "")
-	ErrAppTitleMismatch    = verror2.Register(pkgPath+".AppTitleMismatch", verror2.NoRetry, "")
-	ErrUpdateNoOp          = verror2.Register(pkgPath+".UpdateNoOp", verror2.NoRetry, "")
-	ErrObjectNoExist       = verror2.Register(pkgPath+".ObjectNoExist", verror2.NoRetry, "")
-	ErrInvalidOperation    = verror2.Register(pkgPath+".InvalidOperation", verror2.NoRetry, "")
-	ErrInvalidBlessing     = verror2.Register(pkgPath+".InvalidBlessing", verror2.NoRetry, "")
+	ErrInvalidSuffix       = verror.Register(pkgPath+".InvalidSuffix", verror.NoRetry, "{1:}{2:} invalid suffix{:_}")
+	ErrOperationFailed     = verror.Register(pkgPath+".OperationFailed", verror.NoRetry, "{1:}{2:} operation failed{:_}")
+	ErrOperationInProgress = verror.Register(pkgPath+".OperationInProgress", verror.NoRetry, "{1:}{2:} operation in progress{:_}")
+	ErrAppTitleMismatch    = verror.Register(pkgPath+".AppTitleMismatch", verror.NoRetry, "{1:}{2:} app title mismatch{:_}")
+	ErrUpdateNoOp          = verror.Register(pkgPath+".UpdateNoOp", verror.NoRetry, "{1:}{2:} update is no op{:_}")
+	ErrInvalidOperation    = verror.Register(pkgPath+".InvalidOperation", verror.NoRetry, "{1:}{2:} invalid operation{:_}")
+	ErrInvalidBlessing     = verror.Register(pkgPath+".InvalidBlessing", verror.NoRetry, "{1:}{2:} invalid blessing{:_}")
 )
 
 // NewDispatcher is the device manager dispatcher factory.
@@ -164,17 +162,17 @@
 	// Get the blessings to be used by the claimant.
 	blessings := ctx.Blessings()
 	if blessings == nil {
-		return verror2.Make(ErrInvalidBlessing, ctx)
+		return verror.Make(ErrInvalidBlessing, ctx)
 	}
 	principal := ctx.LocalPrincipal()
 	if err := principal.AddToRoots(blessings); err != nil {
 		vlog.Errorf("principal.AddToRoots(%s) failed: %v", blessings, err)
-		return verror2.Make(ErrInvalidBlessing, ctx)
+		return verror.Make(ErrInvalidBlessing, ctx)
 	}
 	names := blessings.ForContext(ctx)
 	if len(names) == 0 {
 		vlog.Errorf("No names for claimer(%v) are trusted", blessings)
-		return verror2.Make(ErrOperationFailed, nil)
+		return verror.Make(ErrOperationFailed, nil)
 	}
 	principal.BlessingStore().Set(blessings, security.AllPrincipals)
 	principal.BlessingStore().SetDefault(blessings)
@@ -188,11 +186,11 @@
 	_, etag, err := d.getACL()
 	if err != nil {
 		vlog.Errorf("Failed to getACL:%v", err)
-		return verror2.Make(ErrOperationFailed, nil)
+		return verror.Make(ErrOperationFailed, nil)
 	}
 	if err := d.setACL(principal, acl, etag, true /* store ACL on disk */); err != nil {
 		vlog.Errorf("Failed to setACL:%v", err)
-		return verror2.Make(ErrOperationFailed, nil)
+		return verror.Make(ErrOperationFailed, nil)
 	}
 	return nil
 }
@@ -230,7 +228,7 @@
 	}
 
 	if len(etag) > 0 && etag != curEtag {
-		return verror.Make(access.ErrBadEtag, fmt.Sprintf("etag mismatch in:%s vers:%s", etag, curEtag))
+		return verror.Make(access.BadEtag, nil, etag, curEtag)
 	}
 
 	return writeACLs(principal, aclpath, sigpath, dir, acl)
@@ -287,27 +285,27 @@
 	data, err := ioutil.TempFile(dir, "data")
 	if err != nil {
 		vlog.Errorf("Failed to open tmpfile data:%v", err)
-		return verror2.Make(ErrOperationFailed, nil)
+		return verror.Make(ErrOperationFailed, nil)
 	}
 	defer os.Remove(data.Name())
 	sig, err := ioutil.TempFile(dir, "sig")
 	if err != nil {
 		vlog.Errorf("Failed to open tmpfile sig:%v", err)
-		return verror2.Make(ErrOperationFailed, nil)
+		return verror.Make(ErrOperationFailed, nil)
 	}
 	defer os.Remove(sig.Name())
 	writer, err := serialization.NewSigningWriteCloser(data, sig, principal, nil)
 	if err != nil {
 		vlog.Errorf("Failed to create NewSigningWriteCloser:%v", err)
-		return verror2.Make(ErrOperationFailed, nil)
+		return verror.Make(ErrOperationFailed, nil)
 	}
 	if err = acl.WriteTo(writer); err != nil {
 		vlog.Errorf("Failed to SaveACL:%v", err)
-		return verror2.Make(ErrOperationFailed, nil)
+		return verror.Make(ErrOperationFailed, nil)
 	}
 	if err = writer.Close(); err != nil {
 		vlog.Errorf("Failed to Close() SigningWriteCloser:%v", err)
-		return verror2.Make(ErrOperationFailed, nil)
+		return verror.Make(ErrOperationFailed, nil)
 	}
 	if err := os.Rename(data.Name(), aclFile); err != nil {
 		return err
@@ -324,7 +322,7 @@
 	aclFile, sigFile, devicedata := d.getACLFilePaths()
 
 	if len(etag) > 0 && etag != d.etag {
-		return verror.Make(access.ErrBadEtag, fmt.Sprintf("etag mismatch in:%s vers:%s", etag, d.etag))
+		return verror.Make(access.BadEtag, nil, etag, d.etag)
 	}
 	if writeToFile {
 		if err := writeACLs(principal, aclFile, sigFile, devicedata, acl); err != nil {
@@ -396,7 +394,7 @@
 					return nil, nil, err
 				}
 				if !instanceStateIs(appInstanceDir, started) {
-					return nil, nil, verror2.Make(ErrInvalidSuffix, nil)
+					return nil, nil, verror.Make(ErrInvalidSuffix, nil)
 				}
 				var sigStub signatureStub
 				if kind == "pprof" {
@@ -434,7 +432,7 @@
 		return receiver, appSpecificAuthorizer, nil
 	case configSuffix:
 		if len(components) != 2 {
-			return nil, nil, verror2.Make(ErrInvalidSuffix, nil)
+			return nil, nil, verror.Make(ErrInvalidSuffix, nil)
 		}
 		receiver := idevice.ConfigServer(&configService{
 			callback: d.internal.callback,
@@ -449,7 +447,7 @@
 		// (and not other apps).
 		return receiver, nil, nil
 	default:
-		return nil, nil, verror2.Make(ErrInvalidSuffix, nil)
+		return nil, nil, verror.Make(ErrInvalidSuffix, nil)
 	}
 }
 
@@ -479,7 +477,7 @@
 		}
 		return access.TaggedACLAuthorizerFromFile(path.Join(p, "acls", "data"), access.TypicalTagType())
 	}
-	return nil, verror2.Make(ErrInvalidSuffix, nil)
+	return nil, verror.Make(ErrInvalidSuffix, nil)
 }
 
 // allowEveryone implements the authorization policy that allows all principals
diff --git a/services/mgmt/device/impl/impl_test.go b/services/mgmt/device/impl/impl_test.go
index 6ba121e..4f2e138 100644
--- a/services/mgmt/device/impl/impl_test.go
+++ b/services/mgmt/device/impl/impl_test.go
@@ -41,7 +41,7 @@
 	"veyron.io/veyron/veyron2/services/mgmt/stats"
 	"veyron.io/veyron/veyron2/services/security/access"
 	"veyron.io/veyron/veyron2/vdl/vdlutil"
-	"veyron.io/veyron/veyron2/verror"
+	verror "veyron.io/veyron/veyron2/verror2"
 	"veyron.io/veyron/veyron2/vlog"
 
 	"veyron.io/veyron/veyron/lib/expect"
@@ -1405,7 +1405,7 @@
 
 	// Start an instance of the app but this time it should fail: we do not
 	// have an associated uname for the invoking identity.
-	startAppExpectError(t, appID, verror.NoAccess, selfRT)
+	startAppExpectError(t, appID, verror.NoAccess.ID, selfRT)
 
 	// Create an association for selfRT
 	if err := deviceStub.AssociateAccount(selfRT.NewContext(), []string{"root/self"}, testUserName); err != nil {
@@ -1417,7 +1417,7 @@
 	stopApp(t, appID, instance1ID, selfRT)
 
 	vlog.VI(2).Infof("other attempting to run an app without access. Should fail.")
-	startAppExpectError(t, appID, verror.NoAccess, otherRT)
+	startAppExpectError(t, appID, verror.NoAccess.ID, otherRT)
 
 	// Self will now let other also install apps.
 	if err := deviceStub.AssociateAccount(selfRT.NewContext(), []string{"root/other"}, testUserName); err != nil {
@@ -1438,7 +1438,7 @@
 	// other doesn't have execution permissions for the app. So this will
 	// fail.
 	vlog.VI(2).Infof("other attempting to run an app still without access. Should fail.")
-	startAppExpectError(t, appID, verror.NoAccess, otherRT)
+	startAppExpectError(t, appID, verror.NoAccess.ID, otherRT)
 
 	// But self can give other permissions  to start applications.
 	vlog.VI(2).Infof("self attempting to give other permission to start %s", appID)
@@ -1477,7 +1477,7 @@
 	}
 
 	vlog.VI(2).Infof("Show that Resume with a different systemName fails.")
-	resumeAppExpectError(t, appID, instance2ID, verror.NoAccess, otherRT)
+	resumeAppExpectError(t, appID, instance2ID, verror.NoAccess.ID, otherRT)
 
 	// Clean up.
 	stopApp(t, appID, instance2ID, otherRT)
diff --git a/services/mgmt/lib/binary/impl.go b/services/mgmt/lib/binary/impl.go
index 2688fbd..e66a2a6 100644
--- a/services/mgmt/lib/binary/impl.go
+++ b/services/mgmt/lib/binary/impl.go
@@ -17,15 +17,16 @@
 	"veyron.io/veyron/veyron2/context"
 	"veyron.io/veyron/veyron2/services/mgmt/binary"
 	"veyron.io/veyron/veyron2/services/mgmt/repository"
-	"veyron.io/veyron/veyron2/verror"
+	verror "veyron.io/veyron/veyron2/verror2"
 	"veyron.io/veyron/veyron2/vlog"
 
 	"veyron.io/veyron/veyron/services/mgmt/lib/packages"
 )
 
+const pkgPath = "veyron.io/veyron/veyron/services/mgmt/lib/binary"
+
 var (
-	errOperationFailed = verror.Internalf("operation failed")
-	errNotExist        = verror.NoExistf("binary does not exist")
+	errOperationFailed = verror.Register(pkgPath+".errOperationFailed", verror.NoRetry, "{1:}{2:} operation failed{:_}")
 )
 
 const (
@@ -53,7 +54,7 @@
 	}
 	for _, part := range parts {
 		if part.Checksum == binary.MissingChecksum {
-			return repository.MediaInfo{}, errNotExist
+			return repository.MediaInfo{}, verror.Make(verror.NoExist, ctx)
 		}
 	}
 	offset, whence := int64(0), 0
@@ -104,7 +105,7 @@
 			success = true
 		}
 		if !success {
-			return repository.MediaInfo{}, errOperationFailed
+			return repository.MediaInfo{}, verror.Make(errOperationFailed, ctx)
 		}
 		offset += part.Size
 	}
@@ -116,7 +117,7 @@
 	file, err := ioutil.TempFile(dir, prefix)
 	if err != nil {
 		vlog.Errorf("TempFile(%v, %v) failed: %v", dir, prefix, err)
-		return nil, repository.MediaInfo{}, errOperationFailed
+		return nil, repository.MediaInfo{}, verror.Make(errOperationFailed, ctx)
 	}
 	defer os.Remove(file.Name())
 	defer file.Close()
@@ -124,12 +125,12 @@
 	defer cancel()
 	mediaInfo, err := download(ctx, file, von)
 	if err != nil {
-		return nil, repository.MediaInfo{}, errOperationFailed
+		return nil, repository.MediaInfo{}, verror.Make(errOperationFailed, ctx)
 	}
 	bytes, err := ioutil.ReadFile(file.Name())
 	if err != nil {
 		vlog.Errorf("ReadFile(%v) failed: %v", file.Name(), err)
-		return nil, repository.MediaInfo{}, errOperationFailed
+		return nil, repository.MediaInfo{}, verror.Make(errOperationFailed, ctx)
 	}
 	return bytes, mediaInfo, nil
 }
@@ -139,7 +140,7 @@
 	file, err := ioutil.TempFile(dir, prefix)
 	if err != nil {
 		vlog.Errorf("TempFile(%v, %v) failed: %v", dir, prefix, err)
-		return errOperationFailed
+		return verror.Make(errOperationFailed, ctx)
 	}
 	defer file.Close()
 	ctx, cancel := ctx.WithTimeout(time.Minute)
@@ -149,7 +150,7 @@
 		if err := os.Remove(file.Name()); err != nil {
 			vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
 		}
-		return errOperationFailed
+		return verror.Make(errOperationFailed, ctx)
 	}
 	perm := os.FileMode(0600)
 	if err := file.Chmod(perm); err != nil {
@@ -157,21 +158,21 @@
 		if err := os.Remove(file.Name()); err != nil {
 			vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
 		}
-		return errOperationFailed
+		return verror.Make(errOperationFailed, ctx)
 	}
 	if err := os.Rename(file.Name(), path); err != nil {
 		vlog.Errorf("Rename(%v, %v) failed: %v", file.Name(), path, err)
 		if err := os.Remove(file.Name()); err != nil {
 			vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
 		}
-		return errOperationFailed
+		return verror.Make(errOperationFailed, ctx)
 	}
 	if err := packages.SaveMediaInfo(path, mediaInfo); err != nil {
 		vlog.Errorf("packages.SaveMediaInfo(%v, %v) failed: %v", path, mediaInfo, err)
 		if err := os.Remove(path); err != nil {
 			vlog.Errorf("Remove(%v) failed: %v", path, err)
 		}
-		return errOperationFailed
+		return verror.Make(errOperationFailed, ctx)
 	}
 	return nil
 }
@@ -193,7 +194,7 @@
 	size, err := r.Seek(offset, whence)
 	if err != nil {
 		vlog.Errorf("Seek(%v, %v) failed: %v", offset, whence, err)
-		return errOperationFailed
+		return verror.Make(errOperationFailed, ctx)
 	}
 	nparts := (size-1)/partSize + 1
 	if err := client.Create(ctx, int32(nparts), mediaInfo); err != nil {
@@ -272,7 +273,7 @@
 			success = true
 		}
 		if !success {
-			return errOperationFailed
+			return verror.Make(errOperationFailed, ctx)
 		}
 	}
 	return nil
@@ -290,7 +291,7 @@
 	defer file.Close()
 	if err != nil {
 		vlog.Errorf("Open(%v) failed: %v", err)
-		return errOperationFailed
+		return verror.Make(errOperationFailed, ctx)
 	}
 	ctx, cancel := ctx.WithTimeout(time.Minute)
 	defer cancel()
diff --git a/services/mgmt/lib/fs/simplestore.go b/services/mgmt/lib/fs/simplestore.go
index cf1d3b1..329d348 100644
--- a/services/mgmt/lib/fs/simplestore.go
+++ b/services/mgmt/lib/fs/simplestore.go
@@ -12,12 +12,25 @@
 
 	"veyron.io/veyron/veyron/services/mgmt/profile"
 	"veyron.io/veyron/veyron2/services/mgmt/application"
-	"veyron.io/veyron/veyron2/verror"
+	verror "veyron.io/veyron/veyron2/verror2"
 )
 
 // TODO(rjkroege@google.com) Switch Memstore to the mid-August 2014
 // style store API.
 
+const pkgPath = "veyron.io/veyron/veyron/services/mgmt/lib/fs"
+
+// Errors
+var (
+	ErrNoRecursiveCreateTransaction = verror.Register(pkgPath+".ErrNoRecursiveCreateTransaction", verror.NoRetry, "{1:}{2:} recursive CreateTransaction() not permitted{:_}")
+	ErrDoubleCommit                 = verror.Register(pkgPath+".ErrDoubleCommit", verror.NoRetry, "{1:}{2:} illegal attempt to commit previously committed or abandonned transaction{:_}")
+	ErrAbortWithoutTransaction      = verror.Register(pkgPath+".ErrAbortWithoutTransaction", verror.NoRetry, "{1:}{2:} illegal attempt to abort non-existent transaction{:_}")
+	ErrWithoutTransaction           = verror.Register(pkgPath+".ErrRemoveWithoutTransaction", verror.NoRetry, "{1:}{2:} call without a transaction{:_}")
+	ErrNotInMemStore                = verror.Register(pkgPath+".ErrNotInMemStore", verror.NoRetry, "{1:}{2:} not in Memstore{:_}")
+	ErrUnsupportedType              = verror.Register(pkgPath+".ErrUnsupportedType", verror.NoRetry, "{1:}{2:} attempted Put to Memstore of unsupported type{:_}")
+	ErrChildrenWithoutLock          = verror.Register(pkgPath+".ErrChildrenWithoutLock", verror.NoRetry, "{1:}{2:} Children() without a lock{:_}")
+)
+
 // Memstore contains the state of the memstore. It supports a single
 // transaction at a time. The current state of a Memstore under a
 // transactional name binding is the contents of puts then the contents
@@ -175,7 +188,7 @@
 // CreateTransaction requires the caller to acquire a lock on the Memstore.
 func (ms *Memstore) CreateTransaction(_ interface{}) (string, error) {
 	if ms.puts != nil || ms.removes != nil {
-		return "", verror.BadProtocolf("recursive CreateTransaction() not permitted")
+		return "", verror.Make(ErrNoRecursiveCreateTransaction, nil)
 	}
 	ms.newTransactionState()
 	return transactionNamePrefix, nil
@@ -184,7 +197,7 @@
 // Commit updates the store and persists the result.
 func (ms *Memstore) Commit(_ interface{}) error {
 	if !ms.locked || ms.puts == nil || ms.removes == nil {
-		return verror.BadProtocolf("illegal attempt to commit previously committed or abandonned transaction")
+		return verror.Make(ErrDoubleCommit, nil)
 	}
 	for k, v := range ms.puts {
 		ms.data[k] = v
@@ -197,23 +210,23 @@
 
 func (ms *Memstore) Abort(_ interface{}) error {
 	if !ms.locked {
-		return verror.BadProtocolf("illegal attempt to abort non-existent transaction")
+		return verror.Make(ErrAbortWithoutTransaction, nil)
 	}
 	return nil
 }
 
 func (o *boundObject) Remove(_ interface{}) error {
 	if !o.ms.locked {
-		return verror.BadProtocolf("Remove() without a transaction.")
+		return verror.Make(ErrWithoutTransaction, nil, "Remove()")
 	}
 
 	if _, pendingRemoval := o.ms.removes[o.path]; pendingRemoval {
-		return verror.NoExistf("path %s not in Memstore", o.path)
+		return verror.Make(ErrNotInMemStore, nil, o.path)
 	}
 
 	_, found := o.ms.data[o.path]
 	if !found && !o.ms.removeChildren(o.path) {
-		return verror.NoExistf("path %s not in Memstore", o.path)
+		return verror.Make(ErrNotInMemStore, nil, o.path)
 	}
 	delete(o.ms.puts, o.path)
 	o.ms.removes[o.path] = keyExists
@@ -287,7 +300,7 @@
 
 	found := inPuts || (inBase && !inRemoves)
 	if !found {
-		return nil, verror.NoExistf("path %s not in Memstore", o.path)
+		return nil, verror.Make(ErrNotInMemStore, nil, o.path)
 	}
 
 	if inPuts {
@@ -302,7 +315,7 @@
 	bv, inBase := o.ms.data[o.path]
 
 	if !inBase {
-		return nil, verror.NoExistf("path %s not in Memstore", o.path)
+		return nil, verror.Make(ErrNotInMemStore, nil, o.path)
 	}
 
 	o.Value = bv
@@ -319,7 +332,7 @@
 
 func (o *boundObject) Put(_ interface{}, envelope interface{}) (*boundObject, error) {
 	if !o.ms.locked {
-		return nil, verror.BadProtocolf("Put() without a transaction.")
+		return nil, verror.Make(ErrWithoutTransaction, nil, "Put()")
 	}
 	switch v := envelope.(type) {
 	case application.Envelope, profile.Specification:
@@ -328,13 +341,13 @@
 		o.Value = o.path
 		return o, nil
 	default:
-		return o, verror.BadProtocolf("attempted Put to Memstore of unsupported type")
+		return o, verror.Make(ErrUnsupportedType, nil)
 	}
 }
 
 func (o *boundObject) Children() ([]string, error) {
 	if !o.ms.locked {
-		return nil, verror.BadProtocolf("Children() without a lock.")
+		return nil, verror.Make(ErrChildrenWithoutLock, nil)
 	}
 	found := false
 	set := make(map[string]struct{})
@@ -359,7 +372,7 @@
 		}
 	}
 	if !found {
-		return nil, verror.NoExistf("object %q does not exist", o.path)
+		return nil, verror.Make(verror.NoExist, nil, o.path)
 	}
 	children := make([]string, len(set))
 	i := 0
diff --git a/services/mgmt/lib/fs/simplestore_test.go b/services/mgmt/lib/fs/simplestore_test.go
index 9957121..b644f76 100644
--- a/services/mgmt/lib/fs/simplestore_test.go
+++ b/services/mgmt/lib/fs/simplestore_test.go
@@ -11,7 +11,7 @@
 	_ "veyron.io/veyron/veyron/services/mgmt/profile"
 	"veyron.io/veyron/veyron2/naming"
 	"veyron.io/veyron/veyron2/services/mgmt/application"
-	"veyron.io/veyron/veyron2/verror"
+	verror "veyron.io/veyron/veyron2/verror2"
 )
 
 func tempFile(t *testing.T) string {
@@ -247,18 +247,18 @@
 	}
 
 	// At which point, Get() on the transaction won't find anything.
-	if _, err := memstoreOriginal.BindObject(fs.TP("/test/a")).Get(nil); !verror.Is(err, verror.NoExist) {
-		t.Fatalf("Get() should have failed: got %v, expected %v", err, verror.NoExistf("path %s not in Memstore", tname+"/test/a"))
+	if _, err := memstoreOriginal.BindObject(fs.TP("/test/a")).Get(nil); !verror.Is(err, fs.ErrNotInMemStore.ID) {
+		t.Fatalf("Get() should have failed: got %v, expected %v", err, verror.Make(fs.ErrNotInMemStore, nil, tname+"/test/a"))
 	}
 
 	// Attempting to Remove() it over again will fail.
-	if err := memstoreOriginal.BindObject(fs.TP("/test/a")).Remove(nil); !verror.Is(err, verror.NoExist) {
-		t.Fatalf("Remove() should have failed: got %v, expected %v", err, verror.NoExistf("path %s not in Memstore", tname+"/test/a"))
+	if err := memstoreOriginal.BindObject(fs.TP("/test/a")).Remove(nil); !verror.Is(err, fs.ErrNotInMemStore.ID) {
+		t.Fatalf("Remove() should have failed: got %v, expected %v", err, verror.Make(fs.ErrNotInMemStore, nil, tname+"/test/a"))
 	}
 
 	// Attempting to Remove() a non-existing path will fail.
-	if err := memstoreOriginal.BindObject(fs.TP("/foo")).Remove(nil); !verror.Is(err, verror.NoExist) {
-		t.Fatalf("Remove() should have failed: got %v, expected %v", err, verror.NoExistf("path %s not in Memstore", tname+"/foo"))
+	if err := memstoreOriginal.BindObject(fs.TP("/foo")).Remove(nil); !verror.Is(err, fs.ErrNotInMemStore.ID) {
+		t.Fatalf("Remove() should have failed: got %v, expected %v", err, verror.Make(fs.ErrNotInMemStore, nil, tname+"/foo"))
 	}
 
 	// Exists() a non-existing path will fail.
@@ -282,8 +282,8 @@
 	}
 
 	// Validate that Get will fail on a non-existent path.
-	if _, err := memstoreOriginal.BindObject("/test/c").Get(nil); !verror.Is(err, verror.NoExist) {
-		t.Fatalf("Get() should have failed: got %v, expected %v", err, verror.NoExistf("path %s not in Memstore", tname+"/test/c"))
+	if _, err := memstoreOriginal.BindObject("/test/c").Get(nil); !verror.Is(err, fs.ErrNotInMemStore.ID) {
+		t.Fatalf("Get() should have failed: got %v, expected %v", err, verror.Make(fs.ErrNotInMemStore, nil, tname+"/test/c"))
 	}
 
 	// Verify that the previous Commit() operations have persisted to
@@ -405,18 +405,18 @@
 
 	// Put outside ot a transaction should fail.
 	bindingTnameTestA := memstoreOriginal.BindObject(naming.Join("fooey", "/test/a"))
-	if _, err := bindingTnameTestA.Put(nil, envelope); !verror.Is(err, verror.BadProtocol) {
-		t.Fatalf("Put() failed: got %v, expected %v", err, verror.BadProtocolf("Put() without a transactional binding"))
+	if _, err := bindingTnameTestA.Put(nil, envelope); !verror.Is(err, fs.ErrWithoutTransaction.ID) {
+		t.Fatalf("Put() failed: got %v, expected %v", err, verror.Make(fs.ErrWithoutTransaction, nil, "Put()"))
 	}
 
 	// Remove outside of a transaction should fail
-	if err := bindingTnameTestA.Remove(nil); !verror.Is(err, verror.BadProtocol) {
-		t.Fatalf("Put() failed: got %v, expected %v", err, verror.BadProtocolf("Remove() without a transactional binding"))
+	if err := bindingTnameTestA.Remove(nil); !verror.Is(err, fs.ErrWithoutTransaction.ID) {
+		t.Fatalf("Put() failed: got %v, expected %v", err, verror.Make(fs.ErrWithoutTransaction, nil, "Remove()"))
 	}
 
 	// Commit outside of a transaction should fail
-	if err := memstoreOriginal.BindTransaction(tname).Commit(nil); !verror.Is(err, verror.BadProtocol) {
-		t.Fatalf("Commit() failed: got %v, expected %v", err, verror.BadProtocolf("illegal attempt to commit previously committed or abandonned transaction"))
+	if err := memstoreOriginal.BindTransaction(tname).Commit(nil); !verror.Is(err, fs.ErrDoubleCommit.ID) {
+		t.Fatalf("Commit() failed: got %v, expected %v", err, verror.Make(fs.ErrDoubleCommit, nil))
 	}
 
 	// Attempt inserting a value at /test/b
@@ -434,8 +434,8 @@
 	memstoreOriginal.Unlock()
 
 	// Remove should definitely fail on an abndonned transaction.
-	if err := bindingTnameTestB.Remove(nil); !verror.Is(err, verror.BadProtocol) {
-		t.Fatalf("Remove() failed: got %v, expected %v", err, verror.Internalf("Remove() without a transactional binding"))
+	if err := bindingTnameTestB.Remove(nil); !verror.Is(err, fs.ErrWithoutTransaction.ID) {
+		t.Fatalf("Remove() failed: got %v, expected %v", err, verror.Make(fs.ErrWithoutTransaction, nil, "Remove()"))
 	}
 }
 
diff --git a/services/mgmt/logreader/impl/logfile.go b/services/mgmt/logreader/impl/logfile.go
index cbf4606..280e5d3 100644
--- a/services/mgmt/logreader/impl/logfile.go
+++ b/services/mgmt/logreader/impl/logfile.go
@@ -14,15 +14,15 @@
 	"veyron.io/veyron/veyron2/ipc"
 	"veyron.io/veyron/veyron2/services/mgmt/logreader"
 	"veyron.io/veyron/veyron2/services/mgmt/logreader/types"
-	"veyron.io/veyron/veyron2/verror"
+	verror "veyron.io/veyron/veyron2/verror2"
 	"veyron.io/veyron/veyron2/vlog"
 )
 
+const pkgPath = "veyron.io/veyron/veyron/services/mgmt/logreader/impl"
+
 var (
-	errCanceled        = verror.Abortedf("operation canceled")
-	errNotFound        = verror.NoExistf("log file not found")
-	errEOF             = verror.Make(types.EOF, "EOF")
-	errOperationFailed = verror.Internalf("operation failed")
+	errEOF             = verror.Register(types.EOF, verror.NoRetry, "{1:}{2:} EOF{:_}")
+	errOperationFailed = verror.Register(pkgPath+".errOperationFailed", verror.NoRetry, "{1:}{2:} operation failed{:_}")
 )
 
 // NewLogFileService returns a new log file server.
@@ -39,7 +39,7 @@
 	// directory. This could happen if suffix contains "../", which get
 	// collapsed by filepath.Join().
 	if !strings.HasPrefix(p, root) {
-		return "", errOperationFailed
+		return "", verror.Make(errOperationFailed, nil, name)
 	}
 	return p, nil
 }
@@ -54,7 +54,7 @@
 }
 
 // Size returns the size of the log file, in bytes.
-func (i *logfileService) Size(ipc.ServerContext) (int64, error) {
+func (i *logfileService) Size(ctx ipc.ServerContext) (int64, error) {
 	vlog.VI(1).Infof("%v.Size()", i.suffix)
 	fname, err := translateNameToFilename(i.root, i.suffix)
 	if err != nil {
@@ -63,13 +63,13 @@
 	fi, err := os.Stat(fname)
 	if err != nil {
 		if os.IsNotExist(err) {
-			return 0, errNotFound
+			return 0, verror.Make(verror.NoExist, ctx, fname)
 		}
 		vlog.Errorf("Stat(%v) failed: %v", fname, err)
-		return 0, errOperationFailed
+		return 0, verror.Make(errOperationFailed, ctx, fname)
 	}
 	if fi.IsDir() {
-		return 0, errOperationFailed
+		return 0, verror.Make(errOperationFailed, ctx, fname)
 	}
 	return fi.Size(), nil
 }
@@ -84,9 +84,9 @@
 	f, err := os.Open(fname)
 	if err != nil {
 		if os.IsNotExist(err) {
-			return 0, errNotFound
+			return 0, verror.Make(verror.NoExist, ctx, fname)
 		}
-		return 0, errOperationFailed
+		return 0, verror.Make(errOperationFailed, ctx, fname)
 	}
 	reader := newFollowReader(ctx, f, startpos, follow)
 	if numEntries == types.AllEntries {
@@ -98,10 +98,10 @@
 			return reader.tell(), nil
 		}
 		if err == io.EOF {
-			return reader.tell(), errEOF
+			return reader.tell(), verror.Make(errEOF, ctx)
 		}
 		if err != nil {
-			return reader.tell(), errOperationFailed
+			return reader.tell(), verror.Make(errOperationFailed, ctx, fname)
 		}
 		if err := ctx.SendStream().Send(types.LogEntry{Position: offset, Line: line}); err != nil {
 			return reader.tell(), err
@@ -112,7 +112,7 @@
 
 // GlobChildren__ returns the list of files in a directory streamed on a
 // channel. The list is empty if the object is a file.
-func (i *logfileService) GlobChildren__(ipc.ServerContext) (<-chan string, error) {
+func (i *logfileService) GlobChildren__(ctx ipc.ServerContext) (<-chan string, error) {
 	vlog.VI(1).Infof("%v.GlobChildren__()", i.suffix)
 	dirName, err := translateNameToFilename(i.root, i.suffix)
 	if err != nil {
@@ -121,9 +121,9 @@
 	stat, err := os.Stat(dirName)
 	if err != nil {
 		if os.IsNotExist(err) {
-			return nil, errNotFound
+			return nil, verror.Make(verror.NoExist, ctx, dirName)
 		}
-		return nil, errOperationFailed
+		return nil, verror.Make(errOperationFailed, ctx, dirName)
 	}
 	if !stat.IsDir() {
 		return nil, nil
diff --git a/services/mgmt/logreader/impl/logfile_test.go b/services/mgmt/logreader/impl/logfile_test.go
index fb7833c..91db6f3 100644
--- a/services/mgmt/logreader/impl/logfile_test.go
+++ b/services/mgmt/logreader/impl/logfile_test.go
@@ -16,7 +16,7 @@
 	"veyron.io/veyron/veyron2/security"
 	"veyron.io/veyron/veyron2/services/mgmt/logreader"
 	"veyron.io/veyron/veyron2/services/mgmt/logreader/types"
-	"veyron.io/veyron/veyron2/verror"
+	verror "veyron.io/veyron/veyron2/verror2"
 )
 
 func startServer(t *testing.T, runtime veyron2.Runtime, disp ipc.Dispatcher) (ipc.Server, string, error) {
@@ -99,7 +99,7 @@
 	// Try to access a file that doesn't exist.
 	lf := logreader.LogFileClient(naming.JoinAddressName(endpoint, "doesntexist"))
 	_, err = lf.Size(runtime.NewContext())
-	if expected := verror.NoExist; !verror.Is(err, expected) {
+	if expected := verror.NoExist.ID; !verror.Is(err, expected) {
 		t.Errorf("unexpected error value, got %v, want: %v", err, expected)
 	}
 
diff --git a/services/mgmt/logreader/impl/reader.go b/services/mgmt/logreader/impl/reader.go
index 97d1272..301a9c4 100644
--- a/services/mgmt/logreader/impl/reader.go
+++ b/services/mgmt/logreader/impl/reader.go
@@ -7,6 +7,7 @@
 	"time"
 
 	"veyron.io/veyron/veyron2/ipc"
+	verror "veyron.io/veyron/veyron2/verror2"
 )
 
 // followReader implements the functionality of io.Reader, plus:
@@ -46,7 +47,7 @@
 		if f.ctx != nil {
 			select {
 			case <-f.ctx.Done():
-				return 0, errCanceled
+				return 0, verror.Make(verror.Cancelled, nil)
 			default:
 			}
 		}
diff --git a/services/mgmt/pprof/impl/server.go b/services/mgmt/pprof/impl/server.go
index 21e300d..fd05f30 100644
--- a/services/mgmt/pprof/impl/server.go
+++ b/services/mgmt/pprof/impl/server.go
@@ -9,7 +9,15 @@
 
 	"veyron.io/veyron/veyron2/ipc"
 	spprof "veyron.io/veyron/veyron2/services/mgmt/pprof"
-	"veyron.io/veyron/veyron2/verror"
+	verror "veyron.io/veyron/veyron2/verror2"
+)
+
+const pkgPath = "veyron.io/veyron/veyron/services/mgmt/pprof/impl"
+
+// Errors
+var (
+	errNoProfile      = verror.Register(pkgPath+".errNoProfile", verror.NoRetry, "{1:}{2:} profile does not exist{:_}")
+	errInvalidSeconds = verror.Register(pkgPath+".errInvalidSeconds", verror.NoRetry, "{1:}{2:} invalid number of seconds{:_}")
 )
 
 // NewPProfService returns a new pprof service implementation.
@@ -43,10 +51,10 @@
 func (pprofService) Profile(ctx spprof.PProfProfileContext, name string, debug int32) error {
 	profile := pprof.Lookup(name)
 	if profile == nil {
-		return verror.NoExistf("profile does not exist")
+		return verror.Make(errNoProfile, ctx, name)
 	}
 	if err := profile.WriteTo(&streamWriter{ctx.SendStream()}, int(debug)); err != nil {
-		return verror.Convert(err)
+		return verror.Convert(verror.Unknown, ctx, err)
 	}
 	return nil
 }
@@ -55,10 +63,10 @@
 // streams the profile data.
 func (pprofService) CPUProfile(ctx spprof.PProfCPUProfileContext, seconds int32) error {
 	if seconds <= 0 || seconds > 3600 {
-		return verror.BadArgf("invalid number of seconds: %d", seconds)
+		return verror.Make(errInvalidSeconds, ctx, seconds)
 	}
 	if err := pprof.StartCPUProfile(&streamWriter{ctx.SendStream()}); err != nil {
-		return verror.Convert(err)
+		return verror.Convert(verror.Unknown, ctx, err)
 	}
 	time.Sleep(time.Duration(seconds) * time.Second)
 	pprof.StopCPUProfile()
diff --git a/services/mgmt/stats/impl/stats.go b/services/mgmt/stats/impl/stats.go
index f51b12b..be098d5 100644
--- a/services/mgmt/stats/impl/stats.go
+++ b/services/mgmt/stats/impl/stats.go
@@ -14,7 +14,7 @@
 	"veyron.io/veyron/veyron2/services/watch"
 	watchtypes "veyron.io/veyron/veyron2/services/watch/types"
 	"veyron.io/veyron/veyron2/vdl/vdlutil"
-	"veyron.io/veyron/veyron2/verror"
+	verror "veyron.io/veyron/veyron2/verror2"
 	"veyron.io/veyron/veyron2/vlog"
 )
 
@@ -23,10 +23,11 @@
 	watchFreq time.Duration
 }
 
+const pkgPath = "veyron.io/veyron/veyron/services/mgmt/stats/impl"
+
 var (
-	errNotFound        = verror.NoExistf("object not found")
-	errNoValue         = verror.Make(types.NoValue, "object has no value")
-	errOperationFailed = verror.Internalf("operation failed")
+	errNoValue         = verror.Register(types.NoValue, verror.NoRetry, "{1:}{2:} object has no value{:_}")
+	errOperationFailed = verror.Register(pkgPath+".errOperationFailed", verror.NoRetry, "{1:}{2:} operation failed{:_}")
 )
 
 // NewStatsService returns a stats server implementation. The value of watchFreq
@@ -76,9 +77,9 @@
 		}
 		if err := it.Err(); err != nil {
 			if err == libstats.ErrNotFound {
-				return errNotFound
+				return verror.Make(verror.NoExist, ctx, i.suffix)
 			}
-			return errOperationFailed
+			return verror.Make(errOperationFailed, ctx, i.suffix)
 		}
 		for _, change := range changes {
 			if err := ctx.SendStream().Send(change); err != nil {
@@ -101,12 +102,12 @@
 	v, err := libstats.Value(i.suffix)
 	switch err {
 	case libstats.ErrNotFound:
-		return nil, errNotFound
+		return nil, verror.Make(verror.NoExist, ctx, i.suffix)
 	case libstats.ErrNoValue:
-		return nil, errNoValue
+		return nil, verror.Make(errNoValue, ctx, i.suffix)
 	case nil:
 		return v, nil
 	default:
-		return nil, errOperationFailed
+		return nil, verror.Make(errOperationFailed, ctx, i.suffix)
 	}
 }
diff --git a/tools/debug/testdata/integration_test.go b/tools/debug/testdata/integration_test.go
new file mode 100644
index 0000000..86be0c9
--- /dev/null
+++ b/tools/debug/testdata/integration_test.go
@@ -0,0 +1,107 @@
+package testdata
+
+import (
+	"fmt"
+	"os"
+	"path/filepath"
+	"strconv"
+	"strings"
+	"testing"
+
+	"veyron.io/veyron/veyron/lib/modules"
+	"veyron.io/veyron/veyron/lib/testutil/integration"
+
+	_ "veyron.io/veyron/veyron/profiles/static"
+)
+
+func TestHelperProcess(t *testing.T) {
+	modules.DispatchInTest()
+}
+
+func TestDebugGlob(t *testing.T) {
+	env := integration.NewTestEnvironment(t)
+	defer env.Cleanup()
+
+	binary := env.BuildGoPkg("veyron.io/veyron/veyron/tools/debug")
+	inv := binary.Start("glob", env.RootMT()+"/__debug/*")
+
+	var want string
+	for _, entry := range []string{"logs", "pprof", "stats", "vtrace"} {
+		want += env.RootMT() + "/__debug/" + entry + "\n"
+	}
+	if got := inv.Output(); got != want {
+		t.Fatalf("unexpected output, want %s, got %s", want, got)
+	}
+}
+
+func TestDebugGlobLogs(t *testing.T) {
+	env := integration.NewTestEnvironment(t)
+	defer env.Cleanup()
+
+	fileName := filepath.Base(env.TempFile().Name())
+	binary := env.BuildGoPkg("veyron.io/veyron/veyron/tools/debug")
+	output := binary.Start("glob", env.RootMT()+"/__debug/logs/*").Output()
+
+	// The output should contain the filename.
+	want := "/logs/" + fileName
+	if !strings.Contains(output, want) {
+		t.Fatalf("output should contain %s but did not\n%s", want, output)
+	}
+}
+
+func TestReadHostname(t *testing.T) {
+	env := integration.NewTestEnvironment(t)
+	defer env.Cleanup()
+
+	path := env.RootMT() + "/__debug/stats/system/hostname"
+	binary := env.BuildGoPkg("veyron.io/veyron/veyron/tools/debug")
+	got := binary.Start("stats", "read", path).Output()
+	hostname, err := os.Hostname()
+	if err != nil {
+		t.Fatalf("Hostname() failed: %v", err)
+	}
+	if want := path + ": " + hostname + "\n"; got != want {
+		t.Fatalf("unexpected output, want %s, got %s", want, got)
+	}
+}
+
+func TestLogSize(t *testing.T) {
+	env := integration.NewTestEnvironment(t)
+	defer env.Cleanup()
+
+	binary := env.BuildGoPkg("veyron.io/veyron/veyron/tools/debug")
+	f := env.TempFile()
+	testLogData := []byte("This is a test log file")
+	f.Write(testLogData)
+
+	// Check to ensure the file size is accurate
+	str := strings.TrimSpace(binary.Start("logs", "size", env.RootMT()+"/__debug/logs/"+filepath.Base(f.Name())).Output())
+	got, err := strconv.Atoi(str)
+	if err != nil {
+		t.Fatalf("Atoi(\"%q\") failed", str)
+	}
+	want := len(testLogData)
+	if got != want {
+		t.Fatalf("unexpected output, want %d, got %d", got, want)
+	}
+}
+
+func TestStatsRead(t *testing.T) {
+	env := integration.NewTestEnvironment(t)
+	defer env.Cleanup()
+
+	binary := env.BuildGoPkg("veyron.io/veyron/veyron/tools/debug")
+	file := env.TempFile()
+	testLogData := []byte("This is a test log file\n")
+	file.Write(testLogData)
+	logName := filepath.Base(file.Name())
+	runCount := 12
+	for i := 0; i < runCount; i++ {
+		binary.Start("logs", "read", env.RootMT()+"/__debug/logs/"+logName).Wait(nil, nil)
+	}
+	got := binary.Start("stats", "read", env.RootMT()+"/__debug/stats/ipc/server/routing-id/*/methods/ReadLog/latency-ms").Output()
+	want := fmt.Sprintf("Count: %d", runCount)
+	if !strings.Contains(got, want) {
+		t.Fatalf("expected output to contain %s, but did not\n", want, got)
+	}
+}
diff --git a/tools/principal/main.go b/tools/principal/main.go
index dfbfd1a..62b4f61 100644
--- a/tools/principal/main.go
+++ b/tools/principal/main.go
@@ -39,11 +39,9 @@
 	flagSeekBlessingsSetDefault bool
 	flagSeekBlessingsForPeer    string
 
-	// Flag for the create command
-	flagCreateOverwrite bool
-
 	// Flags common to many commands
-	flagAddToRoots bool
+	flagAddToRoots      bool
+	flagCreateOverwrite bool
 
 	// Flags for the "recvblessings" command
 	flagRecvBlessingsSetDefault bool
@@ -172,7 +170,7 @@
 		Long: `
 Bless another principal.
 
-The blesser is obtained from the runtime this tool is using.  The blessing that
+The blesser is obtained from the runtime this tool is using. The blessing that
 will be extended is the default one from the blesser's store, or specified by
 the --with flag. Caveats on the blessing are controlled via the --for flag.
 
@@ -456,16 +454,16 @@
 		Short: "Create a new principal and persist it into a directory",
 		Long: `
 Creates a new principal with a single self-blessed blessing and writes it out
-to the provided directory. The same directory can be used to set the VEYRON_CREDENTIALS
-environment variables for other veyron applications.
+to the provided directory. The same directory can then be used to set the
+VEYRON_CREDENTIALS environment variable for other veyron applications.
 
 The operation fails if the directory already contains a principal. In this case
-the --overwrite flag can be provided to clear the directory and write out a
+the --overwrite flag can be provided to clear the directory and write out the
 new principal.
 `,
 		ArgsName: "<directory> <blessing>",
 		ArgsLong: `
-	<directory> is the directory to which the principal will be persisted.
+	<directory> is the directory to which the new principal will be persisted.
 	<blessing> is the self-blessed blessing that the principal will be setup to use by default.
 	`,
 		Run: func(cmd *cmdline.Command, args []string) error {
@@ -474,18 +472,12 @@
 			}
 			dir, name := args[0], args[1]
 			// TODO(suharshs,ashankar,ataly): How should we make an ecrypted pk... or is that up to the agent?
-			var (
-				p   security.Principal
-				err error
-			)
 			if flagCreateOverwrite {
-				if err = os.RemoveAll(dir); err != nil {
+				if err := os.RemoveAll(dir); err != nil {
 					return err
 				}
-				p, err = vsecurity.CreatePersistentPrincipal(dir, nil)
-			} else {
-				p, err = vsecurity.CreatePersistentPrincipal(dir, nil)
 			}
+			p, err := vsecurity.CreatePersistentPrincipal(dir, nil)
 			if err != nil {
 				return err
 			}
@@ -493,14 +485,81 @@
 			if err != nil {
 				return fmt.Errorf("BlessSelf(%q) failed: %v", name, err)
 			}
-			if err := p.BlessingStore().SetDefault(blessings); err != nil {
-				return fmt.Errorf("BlessingStore.SetDefault(%v) failed: %v", blessings, err)
+			if err := vsecurity.SetDefaultBlessings(p, blessings); err != nil {
+				return fmt.Errorf("could not set blessings %v as default: %v", blessings, err)
 			}
-			if _, err := p.BlessingStore().Set(blessings, security.AllPrincipals); err != nil {
-				return fmt.Errorf("BlessingStore.Set(%v, %q) failed: %v", blessings, security.AllPrincipals, err)
+			return nil
+		},
+	}
+
+	cmdFork = &cmdline.Command{
+		Name:  "fork",
+		Short: "Fork a new principal from the principal that this tool is running as and persist it into a directory",
+		Long: `
+Creates a new principal with a blessing from the principal specified by the
+environment that this tool is running in, and writes it out to the provided
+directory. The blessing that will be extended is the default one from the
+blesser's store, or specified by the --with flag. Caveats on the blessing
+are controlled via the --for flag. The blessing is marked as default and
+shareable with all peers on the new principal's blessing store.
+
+The operation fails if the directory already contains a principal. In this case
+the --overwrite flag can be provided to clear the directory and write out the
+forked principal.
+`,
+		ArgsName: "<directory> <extension>",
+		ArgsLong: `
+	<directory> is the directory to which the forked principal will be persisted.
+	<extension> is the extension under which the forked principal is blessed.
+	`,
+		Run: func(cmd *cmdline.Command, args []string) error {
+			if len(args) != 2 {
+				return fmt.Errorf("requires exactly two arguments: <directory> and <extension>, provided %d", len(args))
 			}
-			if err := p.AddToRoots(blessings); err != nil {
-				return fmt.Errorf("AddToRoots(%v) failed: %v", blessings, err)
+			dir, extension := args[0], args[1]
+
+			if flagCreateOverwrite {
+				if err := os.RemoveAll(dir); err != nil {
+					return err
+				}
+			}
+			p, err := vsecurity.CreatePersistentPrincipal(dir, nil)
+			if err != nil {
+				return err
+			}
+
+			runtime, err := rt.New()
+			if err != nil {
+				return err
+			}
+			defer runtime.Cleanup()
+
+			var (
+				with    security.Blessings
+				caveats []security.Caveat
+			)
+			if len(flagBlessWith) > 0 {
+				if with, err = decodeBlessings(flagBlessWith); err != nil {
+					return fmt.Errorf("failed to read blessings from --with=%q: %v", flagBlessWith, err)
+				}
+			} else {
+				with = runtime.Principal().BlessingStore().Default()
+			}
+			if c, err := security.ExpiryCaveat(time.Now().Add(flagBlessFor)); err != nil {
+				return fmt.Errorf("failed to create ExpiryCaveat: %v", err)
+			} else {
+				caveats = append(caveats, c)
+			}
+			// TODO(ashankar,ataly,suharshs): Work out how to add additional caveats, like maybe
+			// revocation, method etc.
+
+			key := p.PublicKey()
+			blessings, err := runtime.Principal().Bless(key, with, extension, caveats[0], caveats[1:]...)
+			if err != nil {
+				return fmt.Errorf("Bless(%v, %v, %q, ...) failed: %v", key, with, extension, err)
+			}
+			if err := vsecurity.SetDefaultBlessings(p, blessings); err != nil {
+				return fmt.Errorf("could not set blessings %v as default: %v", blessings, err)
 			}
 			return nil
 		},
@@ -671,6 +730,9 @@
 	cmdStoreSetDefault.Flags.BoolVar(&flagAddToRoots, "add_to_roots", true, "If true, the root certificate of the blessing will be added to the principal's set of recognized root certificates")
 
 	cmdCreate.Flags.BoolVar(&flagCreateOverwrite, "overwrite", false, "If true, any existing principal data in the directory will be overwritten")
+	cmdFork.Flags.BoolVar(&flagCreateOverwrite, "overwrite", false, "If true, any existing principal data in the directory will be overwritten")
+	cmdFork.Flags.DurationVar(&flagBlessFor, "for", time.Minute, "Duration of blessing validity")
+	cmdFork.Flags.StringVar(&flagBlessWith, "with", "", "Path to file containing blessing to extend")
 
 	cmdRecvBlessings.Flags.BoolVar(&flagRecvBlessingsSetDefault, "set_default", true, "If true, the blessings received will be set as the default blessing in the store")
 	cmdRecvBlessings.Flags.StringVar(&flagRecvBlessingsForPeer, "for_peer", string(security.AllPrincipals), "If non-empty, the blessings received will be marked for peers matching this pattern in the store")
@@ -695,7 +757,7 @@
 
 All objects are printed using base64-VOM-encoding.
 `,
-		Children: []*cmdline.Command{cmdCreate, cmdSeekBlessings, cmdRecvBlessings, cmdDump, cmdDumpBlessings, cmdBlessSelf, cmdBless, cmdStore},
+		Children: []*cmdline.Command{cmdCreate, cmdFork, cmdSeekBlessings, cmdRecvBlessings, cmdDump, cmdDumpBlessings, cmdBlessSelf, cmdBless, cmdStore},
 	}).Main()
 }
 
diff --git a/tools/principal/test.sh b/tools/principal/test.sh
index 9761be0..b6404df 100755
--- a/tools/principal/test.sh
+++ b/tools/principal/test.sh
@@ -84,11 +84,21 @@
   SEND_BLESSINGS_CMD="${PRINCIPAL_BIN_DIR}/${SEND_BLESSINGS_CMD}"
   $(${SEND_BLESSINGS_CMD} 2>error) && shell_test::fail "line ${LINENO}: ${SEND_BLESSINGS_CMD} should have failed"
   grep "blessings received from unexpected sender" error >/dev/null || shell_test::fail "line ${LINENO}: unexpected sender error not printed"
+  kill -9 "${RECV_BLESSINGS_PID}"
   # Dump carol out, the only blessing that survives should be from the first
   # "bless" command. (alice/friend/carol).
-  kill -9 "${RECV_BLESSINGS_PID}"
   "${PRINCIPAL_BIN}" --veyron.credentials=./carol dump >carol.dump || shell_test::fail "line ${LINENO}: dump failed"
 
+  # Run fork to setup up credentials for alice-phone that are blessed by alice under the extension "phone".
+  "${PRINCIPAL_BIN}" --veyron.credentials=./alice fork ./alice-phone "phone" >/dev/null || shell_test::fail "line ${LINENO}: fork failed"
+  # Dump alice-phone out, the only blessings it has must be from alice (alice/phone).
+  "${PRINCIPAL_BIN}" --veyron.credentials=./alice-phone dump >alice-phone.dump || shell_test::fail "line ${LINENO}: dump failed"
+
+  # Run fork to setup up credentials for alice-phone-calendar that are blessed by alice-phone under the extension "calendar".
+  "${PRINCIPAL_BIN}" --veyron.credentials=./alice-phone fork ./alice-phone-calendar "calendar" >/dev/null || shell_test::fail "line ${LINENO}: fork failed"
+  # Dump alice-phone-calendar out, the only blessings it has must be from alice-phone (alice/phone/calendar).
+  "${PRINCIPAL_BIN}" --veyron.credentials=./alice-phone-calendar dump >alice-phone-calendar.dump || shell_test::fail "line ${LINENO}: dump failed"
+
   # Any other commands to be run without VEYRON_CREDENTIALS set.
   unset VEYRON_CREDENTIALS
 
@@ -166,6 +176,36 @@
   if ! diff -C 5 got want; then
     shell_test::fail "line ${LINENO}"
   fi
+
+  cat alice-phone.dump | rmpublickey >got || shell_test::fail "line ${LINENO}: cat alice-phone.dump | rmpublickey failed"
+  cat >want <<EOF
+Public key : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
+---------------- BlessingStore ----------------
+Default blessings: alice/phone
+Peer pattern                   : Blessings
+...                            : alice/phone
+---------------- BlessingRoots ----------------
+Public key                                      : Pattern
+XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX : [alice/...]
+EOF
+  if ! diff -C 5 got want; then
+    shell_test::fail "line ${LINENO}"
+  fi
+
+  cat alice-phone-calendar.dump | rmpublickey >got || shell_test::fail "line ${LINENO}: cat alice-phone-calendar.dump | rmpublickey failed"
+  cat >want <<EOF
+Public key : XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
+---------------- BlessingStore ----------------
+Default blessings: alice/phone/calendar
+Peer pattern                   : Blessings
+...                            : alice/phone/calendar
+---------------- BlessingRoots ----------------
+Public key                                      : Pattern
+XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX : [alice/...]
+EOF
+  if ! diff -C 5 got want; then
+    shell_test::fail "line ${LINENO}"
+  fi
   shell_test::pass
 }