1// Copyright 2016 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <errno.h> 6#include <fcntl.h> 7#include <getopt.h> 8#include <stdarg.h> 9#include <stdbool.h> 10#include <stdio.h> 11#include <stdlib.h> 12#include <string.h> 13#include <sys/stat.h> 14#include <unistd.h> 15 16#include <fs-management/mount.h> 17#include <lib/fdio/util.h> 18#include <zircon/compiler.h> 19#include <zircon/processargs.h> 20#include <zircon/syscalls.h> 21 22struct { 23 const char* name; 24 disk_format_t df; 25} FILESYSTEMS[] = { 26 {"blobfs", DISK_FORMAT_BLOBFS}, 27 {"minfs", DISK_FORMAT_MINFS}, 28 {"fat", DISK_FORMAT_FAT}, 29}; 30 31int usage(void) { 32 fprintf(stderr, "usage: mkfs [ <option>* ] devicepath filesystem\n"); 33 fprintf(stderr, " -h|--help Print this message\n"); 34 fprintf(stderr, " -v|--verbose Verbose mode\n"); 35 fprintf(stderr, 36 " -s|--fvm_data_slices SLICES If block device is on top of a FVM,\n" 37 " the filesystem will have at least SLICES slices " 38 " allocated for data.\n"); 39 fprintf(stderr, " values for 'filesystem' include:\n"); 40 for (size_t i = 0; i < countof(FILESYSTEMS); i++) { 41 fprintf(stderr, " '%s'\n", FILESYSTEMS[i].name); 42 } 43 return -1; 44} 45 46int parse_args(int argc, char** argv, mkfs_options_t* options, disk_format_t* df, 47 char** devicepath) { 48 static const struct option cmds[] = { 49 {"help", no_argument, NULL, 'h'}, 50 {"verbose", no_argument, NULL, 'v'}, 51 {"fvm_data_slices", required_argument, NULL, 's'}, 52 {0, 0, 0, 0}, 53 }; 54 55 int opt_index = -1; 56 int c = -1; 57 58 while ((c = getopt_long(argc, argv, "hvs:", cmds, &opt_index)) >= 0) { 59 switch (c) { 60 case 'v': 61 options->verbose = true; 62 break; 63 case 's': 64 options->fvm_data_slices = strtoul(optarg, NULL, 0); 65 if (options->fvm_data_slices == 0) { 66 fprintf(stderr, "Invalid Args: %s\n", strerror(errno)); 67 return usage(); 68 } 69 break; 70 case 'h': 71 return usage(); 72 default: 73 break; 74 }; 75 }; 76 77 if (argc - optind < 1) { 78 fprintf(stderr, "Invalid Args: Missing devicepath.\n"); 79 return usage(); 80 } 81 82 if (argc - optind < 2) { 83 fprintf(stderr, "Invalid Args: Missing filesystem.\n"); 84 return usage(); 85 } 86 87 for (size_t i = 0; i < countof(FILESYSTEMS); i++) { 88 if (!strcmp(FILESYSTEMS[i].name, argv[argc - 1])) { 89 *df = FILESYSTEMS[i].df; 90 break; 91 } 92 } 93 94 if (*df == DISK_FORMAT_UNKNOWN) { 95 fprintf(stderr, "fs_mkfs: Cannot format a device with filesystem '%s'\n", argv[2]); 96 return usage(); 97 } 98 99 size_t device_arg = argc - 2; 100 *devicepath = argv[device_arg]; 101 102 return 0; 103} 104 105int main(int argc, char** argv) { 106 mkfs_options_t options = default_mkfs_options; 107 char* devicepath; 108 disk_format_t df; 109 int r; 110 if ((r = parse_args(argc, argv, &options, &df, &devicepath))) { 111 return r; 112 } 113 114 if (options.verbose) { 115 printf("fs_mkfs: Formatting device [%s]\n", devicepath); 116 } 117 118 if ((r = mkfs(devicepath, df, launch_stdio_sync, &options)) < 0) { 119 fprintf(stderr, "fs_mkfs: Failed to format device: %d\n", r); 120 } 121 return r; 122} 123