diff options
author | Ed Tam <etam@google.com> | 2015-04-13 18:01:33 -0700 |
---|---|---|
committer | Ed Tam <etam@google.com> | 2015-04-13 18:01:33 -0700 |
commit | e498c7ca2cdbf4a16aa155bca3357c4ece401854 (patch) | |
tree | ce692fbd672f599211b5d7a11f6f06dfc979db81 | |
parent | 25c39b6aaf6440b4b65bbf0f9f024cff52f5f63b (diff) | |
parent | d0b6de41f8b36df751962e28803db7a4375751ff (diff) | |
download | system_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.mk | 7 | ||||
-rw-r--r-- | fs_mgr/fs_mgr.c | 37 | ||||
-rw-r--r-- | fs_mgr/fs_mgr_format.c | 119 | ||||
-rw-r--r-- | fs_mgr/fs_mgr_fstab.c | 6 | ||||
-rw-r--r-- | fs_mgr/fs_mgr_priv.h | 2 | ||||
-rw-r--r-- | fs_mgr/include/fs_mgr.h | 5 | ||||
-rw-r--r-- | init/Android.mk | 4 | ||||
-rw-r--r-- | init/devices.cpp | 2 | ||||
-rw-r--r-- | init/util.cpp | 2 | ||||
-rw-r--r-- | init/util.h | 2 |
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); |