[make-zxcrypt] Add a small utility to create zxcrypt volumes
This CL adds a command line utility, make-zxcrypt, that will create a
zxcrypt volume with a fixed GUID and a single FVM slice. It's intended
to be used to debug the devcoord hang. DO NOT COMMIT.
Change-Id: Ie11a5960ea4dd049fbb9675fbc71e3922c55e4de
diff --git a/system/uapp/make-zxcrypt/main.cpp b/system/uapp/make-zxcrypt/main.cpp
new file mode 100644
index 0000000..18496d0
--- /dev/null
+++ b/system/uapp/make-zxcrypt/main.cpp
@@ -0,0 +1,67 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdint.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+#include <fbl/unique_fd.h>
+#include <fs-management/fvm.h>
+#include <zircon/device/block.h>
+#include <zircon/status.h>
+#include <zircon/types.h>
+#include <zxcrypt/volume.h>
+
+constexpr uint8_t kDeadbeefGUID[GUID_LEN] = {
+ 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
+ 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef};
+
+// Quick and dirty hack to add a zxcrypt volume to debug devccord hang.
+int main(int argc, char** argv) {
+ if (argc != 2) {
+ fprintf(stderr, "error: wrong number of arguments\n");
+ fprintf(stderr, "usage: %s /path/to/some/fvm\n", argv[0]);
+ return -1;
+ }
+
+ fbl::unique_fd fd(open(argv[1], O_RDONLY));
+ if (!fd) {
+ fprintf(stderr, "error: failed to open '%s'\n", argv[1]);
+ return -1;
+ }
+
+ // Returns an open fd to the new partition on success, -1 on error.
+ alloc_req_t request;
+ request.slice_count = 1;
+ memcpy(request.type, kDeadbeefGUID, sizeof(request.type));
+ memcpy(request.guid, kDeadbeefGUID, sizeof(request.type));
+ snprintf(request.name, NAME_LEN, "deadbeef");
+ request.flags = 0;
+ if (fvm_allocate_partition(fd.get(), &request) < 0) {
+ fprintf(stderr, "warning: failed to allocate FVM partition\n");
+ }
+
+ char path[PATH_MAX];
+ fd.reset(open_partition(kDeadbeefGUID, kDeadbeefGUID, ZX_SEC(3), path));
+ if (!fd) {
+ fprintf(stderr, "error: failed to FVM partition\n");
+ return -1;
+ }
+
+ zx_status_t rc;
+ crypto::Secret key;
+ uint8_t* buf;
+ if ((rc = key.Allocate(zxcrypt::kZx1130KeyLen, &buf)) != ZX_OK) {
+ fprintf(stderr, "error: failed to allocate key: %s\n", zx_status_get_string(rc));
+ return -1;
+ }
+ memset(buf, 0, zxcrypt::kZx1130KeyLen);
+
+ if ((rc = zxcrypt::Volume::Create(fbl::move(fd), key)) != ZX_OK) {
+ fprintf(stderr, "error: failed to create zxcrypt volume: %s\n", zx_status_get_string(rc));
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/system/uapp/make-zxcrypt/rules.mk b/system/uapp/make-zxcrypt/rules.mk
new file mode 100644
index 0000000..c9956ce
--- /dev/null
+++ b/system/uapp/make-zxcrypt/rules.mk
@@ -0,0 +1,37 @@
+# Copyright 2017 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_TYPE := userapp
+
+MODULE_NAME := make-zxcrypt
+
+MODULE_GROUP := core
+
+MODULE_SRCS := \
+ $(LOCAL_DIR)/main.cpp \
+
+MODULE_LIBS := \
+ system/ulib/c \
+ system/ulib/zircon \
+ system/ulib/fdio \
+ system/ulib/crypto \
+ system/ulib/fs-management \
+ system/ulib/zxcrypt \
+
+MODULE_STATIC_LIBS := \
+ third_party/ulib/cryptolib \
+ third_party/ulib/uboringssl \
+ system/ulib/ddk \
+ system/ulib/fvm \
+ system/ulib/fs \
+ system/ulib/sync \
+ system/ulib/zx \
+ system/ulib/zxcpp \
+ system/ulib/fbl \
+
+include make/module.mk
diff --git a/system/ulib/fdio/unistd.c b/system/ulib/fdio/unistd.c
index b5f9f45..ddc092d 100644
--- a/system/ulib/fdio/unistd.c
+++ b/system/ulib/fdio/unistd.c
@@ -24,6 +24,7 @@
#include <zircon/assert.h>
#include <zircon/compiler.h>
+#include <zircon/device/device.h>
#include <zircon/device/vfs.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
@@ -743,6 +744,14 @@
return ZX_ERR_BAD_HANDLE;
}
ssize_t r = io->ops->ioctl(io, op, in_buf, in_len, out_buf, out_len);
+
+ if (r == ZX_ERR_TIMED_OUT) {
+ char path[PATH_MAX];
+ if (io->ops->ioctl(io, IOCTL_DEVICE_GET_TOPO_PATH, NULL, 0, path, PATH_MAX) >= 0) {
+ printf("FDIO ERROR: ioctl to %s timed out\n", path);
+ }
+ }
+
fdio_release(io);
return r;
}