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 <zircon/processargs.h>
18 #include <zircon/syscalls.h>
19 #include <lib/fdio/util.h>
20 
21 
usage(void)22 int usage(void) {
23     fprintf(stderr, "usage: mount [ <option>* ] devicepath mountpath\n"
24                     "options: \n"
25                     " -r|--readonly  : Open the filesystem as read-only\n"
26                     " -m|--metrics   : Collect filesystem metrics\n"
27                     " -v|--verbose   : Verbose mode\n"
28                     " -h|--help      : Display this message\n");
29     return -1;
30 }
31 
parse_args(int argc,char ** argv,mount_options_t * options,char ** devicepath,char ** mountpath)32 int parse_args(int argc, char** argv, mount_options_t* options,
33                char** devicepath, char** mountpath) {
34     while (1) {
35         static struct option opts[] = {
36             {"readonly", no_argument, NULL, 'r'},
37             {"metrics", no_argument, NULL, 'm'},
38             {"journal", no_argument, NULL, 'j'},
39             {"verbose", no_argument, NULL, 'v'},
40             {"help", no_argument, NULL, 'h'},
41             {NULL, 0, NULL, 0},
42         };
43         int opt_index;
44         int c = getopt_long(argc, argv, "rmvh", opts, &opt_index);
45         if (c < 0) {
46             break;
47         }
48         switch (c) {
49         case 'r':
50             options->readonly = true;
51             break;
52         case 'm':
53             options->collect_metrics = true;
54             break;
55         case 'j':
56             options->enable_journal = true;
57             break;
58         case 'v':
59             options->verbose_mount = true;
60             break;
61         case 'h':
62         default:
63             return usage();
64         }
65     }
66 
67     argc -= optind;
68     argv += optind;
69 
70     if (argc < 2) {
71         return usage();
72     }
73     *devicepath = argv[0];
74     *mountpath = argv[1];
75     return 0;
76 }
77 
main(int argc,char ** argv)78 int main(int argc, char** argv) {
79     char* devicepath;
80     char* mountpath;
81     mount_options_t options = default_mount_options;
82     int r;
83     if ((r = parse_args(argc, argv, &options, &devicepath, &mountpath))) {
84         return r;
85     }
86 
87     if (options.verbose_mount) {
88         printf("fs_mount: Mounting device [%s] on path [%s]\n", devicepath, mountpath);
89     }
90 
91     int fd;
92     if ((fd = open(devicepath, O_RDWR)) < 0) {
93         fprintf(stderr, "Error opening block device\n");
94         return -1;
95     }
96     disk_format_t df = detect_disk_format(fd);
97     zx_status_t status = mount(fd, mountpath, df, &options, launch_logs_async);
98     if (status != ZX_OK) {
99         fprintf(stderr, "fs_mount: Error while mounting: %d\n", status);
100     }
101     return status;
102 }
103