16002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall/* 26002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall * Copyright (C) 2011, 2012 The Android Open Source Project 36002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall * 46002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall * Licensed under the Apache License, Version 2.0 (the "License"); 56002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall * you may not use this file except in compliance with the License. 66002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall * You may obtain a copy of the License at 76002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall * 86002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall * http://www.apache.org/licenses/LICENSE-2.0 96002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall * 106002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall * Unless required by applicable law or agreed to in writing, software 116002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall * distributed under the License is distributed on an "AS IS" BASIS, 126002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall * See the License for the specific language governing permissions and 146002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall * limitations under the License. 156002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall */ 166002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 176002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall#include <stdlib.h> 186002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall#include <stdio.h> 196002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall#include <sys/types.h> 206002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall#include <sys/stat.h> 216002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall#include <fcntl.h> 226002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall#include <unistd.h> 236002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall#include <sys/ioctl.h> 246002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall#include <linux/fs.h> 256002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall#include <errno.h> 266002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 276002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumralltypedef unsigned long long u64; 286002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 296002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall#ifndef BLKDISCARD 306002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall#define BLKDISCARD _IO(0x12,119) 316002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall#endif 326002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 336002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall#ifndef BLKSECDISCARD 346002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall#define BLKSECDISCARD _IO(0x12,125) 356002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall#endif 366002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 376002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrallstatic u64 get_block_device_size(int fd) 386002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall{ 396002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall u64 size = 0; 406002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall int ret; 416002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 426002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall ret = ioctl(fd, BLKGETSIZE64, &size); 436002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 446002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall if (ret) 456002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall return 0; 466002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 476002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall return size; 486002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall} 496002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 506002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrallstatic int wipe_block_device(int fd, u64 len, int secure) 516002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall{ 526002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall u64 range[2]; 536002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall int ret; 546002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall int req; 556002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 566002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall range[0] = 0; 576002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall range[1] = len; 586002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall if (secure) { 596002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall req = BLKSECDISCARD; 606002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall } else { 616002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall req = BLKDISCARD; 626002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall } 636002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 646002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall ret = ioctl(fd, req, &range); 656002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall if (ret < 0) { 666002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall fprintf(stderr, "%s discard failed, errno = %d\n", 676002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall secure ? "Secure" : "Nonsecure", errno); 686002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall } 696002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 706002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall return ret; 716002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall} 726002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 736002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrallstatic void usage(void) 746002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall{ 756002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall fprintf(stderr, "Usage: wipe_blkdev [-s] <partition>\n"); 766002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall exit(1); 776002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall} 786002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 796002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrallint main(int argc, char *argv[]) 806002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall{ 816002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall int secure = 0; 826002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall char *devname; 836002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall int fd; 846002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall u64 len; 856002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall struct stat statbuf; 866002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall int ret; 876002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 886002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall if ((argc != 2) && (argc != 3)) { 896002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall usage(); 906002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall } 916002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 926002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall if (argc == 3) { 936002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall if (!strcmp(argv[1], "-s")) { 946002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall secure = 1; 956002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall devname = argv[2]; 966002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall } else { 976002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall usage(); 986002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall } 996002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall } else { 1006002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall devname = argv[1]; 1016002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall } 1026002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 1036002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall fd = open(devname, O_RDWR); 1046002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall if (fd < 0) { 1056002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall fprintf(stderr, "Cannot open device %s\n", devname); 1066002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall exit(1); 1076002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall } 1086002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 1096002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall if (fstat(fd, &statbuf) < 0) { 1106002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall fprintf(stderr, "Cannot stat %s\n", devname); 1116002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall exit(1); 1126002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall } 1136002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 1146002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall if (!S_ISBLK(statbuf.st_mode)) { 1156002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall fprintf(stderr, "%s is not a block device\n", devname); 1166002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall exit(1); 1176002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall } 1186002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 1196002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall len = get_block_device_size(fd); 1206002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 1216002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall if (! len) { 1226002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall fprintf(stderr, "Cannot get size of block device %s\n", devname); 1236002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall exit(1); 1246002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall } 1256002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 1266002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall ret = wipe_block_device(fd, len, secure); 1276002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 1286002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall close(fd); 1296002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall 1306002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall return ret; 1316002c64f41c3e169e68eeb4c5272c6ec63642514Ken Sumrall} 132