summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Tam <etam@google.com>2015-04-13 18:01:33 -0700
committerEd Tam <etam@google.com>2015-04-13 18:01:33 -0700
commite498c7ca2cdbf4a16aa155bca3357c4ece401854 (patch)
treece692fbd672f599211b5d7a11f6f06dfc979db81
parent25c39b6aaf6440b4b65bbf0f9f024cff52f5f63b (diff)
parentd0b6de41f8b36df751962e28803db7a4375751ff (diff)
downloadsystem_core-e498c7ca2cdbf4a16aa155bca3357c4ece401854.zip
system_core-e498c7ca2cdbf4a16aa155bca3357c4ece401854.tar.gz
system_core-e498c7ca2cdbf4a16aa155bca3357c4ece401854.tar.bz2
resolved conflicts for merge of d0b6de41 to master
Change-Id: I1d1f6b1cdbd7ee441682c4258a11fb3198ca7d94
-rw-r--r--fs_mgr/Android.mk7
-rw-r--r--fs_mgr/fs_mgr.c37
-rw-r--r--fs_mgr/fs_mgr_format.c119
-rw-r--r--fs_mgr/fs_mgr_fstab.c6
-rw-r--r--fs_mgr/fs_mgr_priv.h2
-rw-r--r--fs_mgr/include/fs_mgr.h5
-rw-r--r--init/Android.mk4
-rw-r--r--init/devices.cpp2
-rw-r--r--init/util.cpp2
-rw-r--r--init/util.h2
10 files changed, 177 insertions, 9 deletions
diff --git a/fs_mgr/Android.mk b/fs_mgr/Android.mk
index 08d0671..8ed5cc9 100644
--- a/fs_mgr/Android.mk
+++ b/fs_mgr/Android.mk
@@ -4,8 +4,12 @@ LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= fs_mgr.c fs_mgr_verity.c fs_mgr_fstab.c
+LOCAL_SRC_FILES += fs_mgr_format.c
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include \
+ system/vold \
+ system/extras/ext4_utils \
+ external/openssl/include
LOCAL_MODULE:= libfs_mgr
LOCAL_STATIC_LIBRARIES := liblogwrap libmincrypt libext4_utils_static libsquashfs_utils
@@ -35,6 +39,7 @@ LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)/sbin
LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED)
LOCAL_STATIC_LIBRARIES := libfs_mgr liblogwrap libcutils liblog libc libmincrypt libext4_utils_static libsquashfs_utils
+LOCAL_STATIC_LIBRARIES += libsparse_static libz libselinux
LOCAL_CXX_STL := libc++_static
LOCAL_CFLAGS := -Werror
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index 273a2ec..eb10642 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -44,6 +44,9 @@
#include "mincrypt/sha.h"
#include "mincrypt/sha256.h"
+#include "ext4_utils.h"
+#include "wipe.h"
+
#include "fs_mgr_priv.h"
#include "fs_mgr_priv_verity.h"
@@ -552,6 +555,8 @@ int fs_mgr_mount_all(struct fstab *fstab)
}
}
int last_idx_inspected;
+ int top_idx = i;
+
mret = mount_with_alternatives(fstab, i, &last_idx_inspected, &attempted_idx);
i = last_idx_inspected;
mount_errno = errno;
@@ -577,10 +582,38 @@ int fs_mgr_mount_all(struct fstab *fstab)
continue;
}
- /* mount(2) returned an error, check if it's encryptable and deal with it */
+ /* mount(2) returned an error, handle the encryptable/formattable case */
+ bool wiped = partition_wiped(fstab->recs[top_idx].blk_device);
+ if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
+ fs_mgr_is_formattable(&fstab->recs[top_idx]) && wiped) {
+ /* top_idx and attempted_idx point at the same partition, but sometimes
+ * at two different lines in the fstab. Use the top one for formatting
+ * as that is the preferred one.
+ */
+ ERROR("%s(): %s is wiped and %s %s is formattable. Format it.\n", __func__,
+ fstab->recs[top_idx].blk_device, fstab->recs[top_idx].mount_point,
+ fstab->recs[top_idx].fs_type);
+ if (fs_mgr_is_encryptable(&fstab->recs[top_idx]) &&
+ strcmp(fstab->recs[top_idx].key_loc, KEY_IN_FOOTER)) {
+ int fd = open(fstab->recs[top_idx].key_loc, O_WRONLY, 0644);
+ if (fd >= 0) {
+ INFO("%s(): also wipe %s\n", __func__, fstab->recs[top_idx].key_loc);
+ wipe_block_device(fd, get_file_size(fd));
+ close(fd);
+ } else {
+ ERROR("%s(): %s wouldn't open (%s)\n", __func__,
+ fstab->recs[top_idx].key_loc, strerror(errno));
+ }
+ }
+ if (fs_mgr_do_format(&fstab->recs[top_idx]) == 0) {
+ /* Let's replay the mount actions. */
+ i = top_idx - 1;
+ continue;
+ }
+ }
if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
- if(partition_wiped(fstab->recs[attempted_idx].blk_device)) {
+ if (wiped) {
ERROR("%s(): %s is wiped and %s %s is encryptable. Suggest recovery...\n", __func__,
fstab->recs[attempted_idx].blk_device, fstab->recs[attempted_idx].mount_point,
fstab->recs[attempted_idx].fs_type);
diff --git a/fs_mgr/fs_mgr_format.c b/fs_mgr/fs_mgr_format.c
new file mode 100644
index 0000000..95c6a74
--- /dev/null
+++ b/fs_mgr/fs_mgr_format.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <cutils/partition_utils.h>
+#include <sys/mount.h>
+#include "ext4_utils.h"
+#include "ext4.h"
+#include "make_ext4fs.h"
+#include "fs_mgr_priv.h"
+
+extern struct fs_info info; /* magic global from ext4_utils */
+extern void reset_ext4fs_info();
+
+static int format_ext4(char *fs_blkdev, char *fs_mnt_point)
+{
+ unsigned int nr_sec;
+ int fd, rc = 0;
+
+ if ((fd = open(fs_blkdev, O_WRONLY, 0644)) < 0) {
+ ERROR("Cannot open block device. %s\n", strerror(errno));
+ return -1;
+ }
+
+ if ((ioctl(fd, BLKGETSIZE, &nr_sec)) == -1) {
+ ERROR("Cannot get block device size. %s\n", strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ /* Format the partition using the calculated length */
+ reset_ext4fs_info();
+ info.len = ((off64_t)nr_sec * 512);
+
+ /* Use make_ext4fs_internal to avoid wiping an already-wiped partition. */
+ rc = make_ext4fs_internal(fd, NULL, fs_mnt_point, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL);
+ if (rc) {
+ ERROR("make_ext4fs returned %d.\n", rc);
+ }
+ close(fd);
+
+ return rc;
+}
+
+static int format_f2fs(char *fs_blkdev)
+{
+ char * args[3];
+ int pid;
+ int rc = 0;
+
+ args[0] = (char *)"/sbin/mkfs.f2fs";
+ args[1] = fs_blkdev;
+ args[2] = (char *)0;
+
+ pid = fork();
+ if (pid < 0) {
+ return pid;
+ }
+ if (!pid) {
+ /* This doesn't return */
+ execv("/sbin/mkfs.f2fs", args);
+ exit(1);
+ }
+ for(;;) {
+ pid_t p = waitpid(pid, &rc, 0);
+ if (p != pid) {
+ ERROR("Error waiting for child process - %d\n", p);
+ rc = -1;
+ break;
+ }
+ if (WIFEXITED(rc)) {
+ rc = WEXITSTATUS(rc);
+ INFO("%s done, status %d\n", args[0], rc);
+ if (rc) {
+ rc = -1;
+ }
+ break;
+ }
+ ERROR("Still waiting for %s...\n", args[0]);
+ }
+
+ return rc;
+}
+
+int fs_mgr_do_format(struct fstab_rec *fstab)
+{
+ int rc = -EINVAL;
+
+ ERROR("%s: Format %s as '%s'.\n", __func__, fstab->blk_device, fstab->fs_type);
+
+ if (!strncmp(fstab->fs_type, "f2fs", 4)) {
+ rc = format_f2fs(fstab->blk_device);
+ } else if (!strncmp(fstab->fs_type, "ext4", 4)) {
+ rc = format_ext4(fstab->blk_device, fstab->mount_point);
+ } else {
+ ERROR("File system type '%s' is not supported\n", fstab->fs_type);
+ }
+
+ return rc;
+}
diff --git a/fs_mgr/fs_mgr_fstab.c b/fs_mgr/fs_mgr_fstab.c
index 4451b82..882585c 100644
--- a/fs_mgr/fs_mgr_fstab.c
+++ b/fs_mgr/fs_mgr_fstab.c
@@ -71,6 +71,7 @@ static struct flag_list fs_mgr_flags[] = {
{ "verify", MF_VERIFY },
{ "noemulatedsd", MF_NOEMULATEDSD },
{ "notrim", MF_NOTRIM },
+ { "formattable", MF_FORMATTABLE },
{ "defaults", 0 },
{ 0, 0 },
};
@@ -454,3 +455,8 @@ int fs_mgr_is_notrim(struct fstab_rec *fstab)
{
return fstab->fs_mgr_flags & MF_NOTRIM;
}
+
+int fs_mgr_is_formattable(struct fstab_rec *fstab)
+{
+ return fstab->fs_mgr_flags & (MF_FORMATTABLE);
+}
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index ee944c1..682fd11 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -78,10 +78,10 @@
external storage */
#define MF_NOTRIM 0x1000
#define MF_FILEENCRYPTION 0x2000
+#define MF_FORMATTABLE 0x4000
#define DM_BUF_SIZE 4096
int fs_mgr_set_blk_ro(const char *blockdev);
#endif /* __CORE_FS_MGR_PRIV_H */
-
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index a1fdf55..27fccf7 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -104,10 +104,13 @@ int fs_mgr_is_encryptable(const struct fstab_rec *fstab);
int fs_mgr_is_file_encrypted(const struct fstab_rec *fstab);
int fs_mgr_is_noemulatedsd(const struct fstab_rec *fstab);
int fs_mgr_is_notrim(struct fstab_rec *fstab);
+int fs_mgr_is_formattable(struct fstab_rec *fstab);
int fs_mgr_swapon_all(struct fstab *fstab);
+
+int fs_mgr_do_format(struct fstab_rec *fstab);
+
#ifdef __cplusplus
}
#endif
#endif /* __CORE_FS_MGR_H */
-
diff --git a/init/Android.mk b/init/Android.mk
index 4bd4f3d..31d2fcd 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -69,7 +69,9 @@ LOCAL_STATIC_LIBRARIES := \
libselinux \
libmincrypt \
libc++_static \
- libdl
+ libdl \
+ libsparse_static \
+ libz
# Create symlinks
LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \
diff --git a/init/devices.cpp b/init/devices.cpp
index 96b1696..5ca855f 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -540,7 +540,7 @@ static void handle_device(const char *action, const char *devpath,
make_device(devpath, path, block, major, minor, (const char **)links);
if (links) {
for (i = 0; links[i]; i++)
- make_link(devpath, links[i]);
+ make_link_init(devpath, links[i]);
}
}
diff --git a/init/util.cpp b/init/util.cpp
index 3b49b30..c0be38f 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -325,7 +325,7 @@ void sanitize(char *s)
}
}
-void make_link(const char *oldpath, const char *newpath)
+void make_link_init(const char *oldpath, const char *newpath)
{
int ret;
char buf[256];
diff --git a/init/util.h b/init/util.h
index 8fec7a8..dfb1d9d 100644
--- a/init/util.h
+++ b/init/util.h
@@ -53,7 +53,7 @@ unsigned int decode_uid(const char *s);
int mkdir_recursive(const char *pathname, mode_t mode);
void sanitize(char *p);
-void make_link(const char *oldpath, const char *newpath);
+void make_link_init(const char *oldpath, const char *newpath);
void remove_link(const char *oldpath, const char *newpath);
int wait_for_file(const char *filename, int timeout);
void open_devnull_stdio(void);