1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) Linux Test Project, 2019-2022
4 * Copyright (c) 2018 FUJITSU LIMITED. All rights reserved.
5 * Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 #define SKIP_DELIMITER ','
13
14 #define TST_NO_DEFAULT_MAIN
15 #include "tst_test.h"
16 #include "tst_fs.h"
17
18 #define err_exit(...) ({ \
19 fprintf(stderr, __VA_ARGS__); \
20 fprintf(stderr, "\n"); \
21 usage(); \
22 exit(2); \
23 })
24
25 #define fail_exit(...) ({ \
26 fprintf(stderr, __VA_ARGS__); \
27 fprintf(stderr, "\n"); \
28 exit(1); \
29 })
30
31 #define info_exit(...) ({ \
32 fprintf(stderr, __VA_ARGS__); \
33 fprintf(stderr, "\n"); \
34 exit(0); \
35 })
36
usage(void)37 static void usage(void)
38 {
39 fprintf(stderr, "Usage:\n");
40 fprintf(stderr, "* all filesystems\n");
41 fprintf(stderr, "tst_supported_fs [-s skip_list]\n");
42 fprintf(stderr, " print the list of supported filesystems\n");
43 fprintf(stderr, " if fs_type is supported and not in skip_list (optional),\n"
44 " print list of supported filesystems and return 0\n");
45 fprintf(stderr, " if fs_type isn't supported or in skip_list, return 1\n\n");
46
47 fprintf(stderr, "* single filesystem\n");
48 fprintf(stderr, "tst_supported_fs fs_type\n");
49 fprintf(stderr, " if fs_type is supported, return 0 otherwise return 1\n\n");
50
51 fprintf(stderr, "tst_supported_fs -s skip_list fs_type\n");
52 fprintf(stderr, " if fs_type is in skip_list, return 1 otherwise return 0\n\n");
53
54 fprintf(stderr, "tst_supported_fs -s skip_list -d path\n");
55 fprintf(stderr, " if filesystem mounted on path is in skip_list, return 1 otherwise return 0\n\n");
56
57 fprintf(stderr, "fs_type - a specified filesystem type\n");
58 fprintf(stderr, "skip_list - filesystems to skip, delimiter: '%c'\n",
59 SKIP_DELIMITER);
60 fprintf(stderr, "path - any valid file or directory\n");
61 }
62
parse_skiplist(char * fs)63 static char **parse_skiplist(char *fs)
64 {
65 char **skiplist;
66 int i, cnt = 1;
67
68 for (i = 0; fs[i]; i++) {
69 if (optarg[i] == SKIP_DELIMITER)
70 cnt++;
71 }
72
73 skiplist = malloc(++cnt * sizeof(char *));
74 if (!skiplist) {
75 fprintf(stderr, "malloc() failed\n");
76 return NULL;
77 }
78
79 for (i = 0; i < cnt; i++)
80 skiplist[i] = strtok_r(fs, TST_TO_STR(SKIP_DELIMITER), &fs);
81
82 return skiplist;
83 }
84
main(int argc,char * argv[])85 int main(int argc, char *argv[])
86 {
87 const char *const *filesystems;
88 const char *fsname = NULL;
89 int i, ret;
90 char **skiplist = NULL;
91
92 while ((ret = getopt(argc, argv, "d:hs:"))) {
93 if (ret < 0)
94 break;
95
96 switch (ret) {
97 case '?':
98 usage();
99 return 2;
100
101 case 'h':
102 usage();
103 return 0;
104
105 case 's':
106 skiplist = parse_skiplist(optarg);
107 if (!skiplist)
108 return 2;
109 break;
110
111 case 'd':
112 if (fsname)
113 err_exit("Can't specify multiple paths");
114
115 fsname = tst_fs_type_name(tst_fs_type(optarg));
116 break;
117 }
118 }
119
120 if (fsname && !skiplist)
121 err_exit("Parameter -d requires skiplist");
122
123 if (argc - optind > 1)
124 err_exit("Can't specify multiple fs_type");
125
126 /* fs_type */
127 if (optind < argc) {
128 if (fsname)
129 err_exit("Can't specify fs_type and -d together");
130
131 fsname = argv[optind];
132 }
133
134 if (fsname) {
135 if (fsname[0] == '\0')
136 err_exit("fs_type is empty");
137
138 if (skiplist) {
139 if (tst_fs_in_skiplist(fsname, (const char * const*)skiplist))
140 fail_exit("%s is skipped", fsname);
141
142 info_exit("%s is not skipped", fsname);
143 }
144
145 if (tst_fs_is_supported(fsname) == TST_FS_UNSUPPORTED)
146 fail_exit("%s is not supported", fsname);
147
148 info_exit("%s is supported", fsname);
149 }
150
151 /* all filesystems */
152 filesystems = tst_get_supported_fs_types((const char * const*)skiplist);
153
154 if (!filesystems[0])
155 fail_exit("There are no supported filesystems or all skipped");
156
157 for (i = 0; filesystems[i]; i++)
158 printf("%s\n", filesystems[i]);
159
160 return 0;
161 }
162