// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) Linux Test Project, 2019-2022 * Copyright (c) 2018 FUJITSU LIMITED. All rights reserved. * Author: Xiao Yang */ #include #include #include #define SKIP_DELIMITER ',' #define TST_NO_DEFAULT_MAIN #include "tst_test.h" #include "tst_fs.h" #define err_exit(...) ({ \ fprintf(stderr, __VA_ARGS__); \ fprintf(stderr, "\n"); \ usage(); \ exit(2); \ }) #define fail_exit(...) ({ \ fprintf(stderr, __VA_ARGS__); \ fprintf(stderr, "\n"); \ exit(1); \ }) #define info_exit(...) ({ \ fprintf(stderr, __VA_ARGS__); \ fprintf(stderr, "\n"); \ exit(0); \ }) static void usage(void) { fprintf(stderr, "Usage:\n"); fprintf(stderr, "* all filesystems\n"); fprintf(stderr, "tst_supported_fs [-s skip_list]\n"); fprintf(stderr, " print the list of supported filesystems\n"); fprintf(stderr, " if fs_type is supported and not in skip_list (optional),\n" " print list of supported filesystems and return 0\n"); fprintf(stderr, " if fs_type isn't supported or in skip_list, return 1\n\n"); fprintf(stderr, "* single filesystem\n"); fprintf(stderr, "tst_supported_fs fs_type\n"); fprintf(stderr, " if fs_type is supported, return 0 otherwise return 1\n\n"); fprintf(stderr, "tst_supported_fs -s skip_list fs_type\n"); fprintf(stderr, " if fs_type is in skip_list, return 1 otherwise return 0\n\n"); fprintf(stderr, "tst_supported_fs -s skip_list -d path\n"); fprintf(stderr, " if filesystem mounted on path is in skip_list, return 1 otherwise return 0\n\n"); fprintf(stderr, "fs_type - a specified filesystem type\n"); fprintf(stderr, "skip_list - filesystems to skip, delimiter: '%c'\n", SKIP_DELIMITER); fprintf(stderr, "path - any valid file or directory\n"); } static char **parse_skiplist(char *fs) { char **skiplist; int i, cnt = 1; for (i = 0; fs[i]; i++) { if (optarg[i] == SKIP_DELIMITER) cnt++; } skiplist = malloc(++cnt * sizeof(char *)); if (!skiplist) { fprintf(stderr, "malloc() failed\n"); return NULL; } for (i = 0; i < cnt; i++) skiplist[i] = strtok_r(fs, TST_TO_STR(SKIP_DELIMITER), &fs); return skiplist; } int main(int argc, char *argv[]) { const char *const *filesystems; const char *fsname = NULL; int i, ret; char **skiplist = NULL; while ((ret = getopt(argc, argv, "d:hs:"))) { if (ret < 0) break; switch (ret) { case '?': usage(); return 2; case 'h': usage(); return 0; case 's': skiplist = parse_skiplist(optarg); if (!skiplist) return 2; break; case 'd': if (fsname) err_exit("Can't specify multiple paths"); fsname = tst_fs_type_name(tst_fs_type(optarg)); break; } } if (fsname && !skiplist) err_exit("Parameter -d requires skiplist"); if (argc - optind > 1) err_exit("Can't specify multiple fs_type"); /* fs_type */ if (optind < argc) { if (fsname) err_exit("Can't specify fs_type and -d together"); fsname = argv[optind]; } if (fsname) { if (fsname[0] == '\0') err_exit("fs_type is empty"); if (skiplist) { if (tst_fs_in_skiplist(fsname, (const char * const*)skiplist)) fail_exit("%s is skipped", fsname); info_exit("%s is not skipped", fsname); } if (tst_fs_is_supported(fsname) == TST_FS_UNSUPPORTED) fail_exit("%s is not supported", fsname); info_exit("%s is supported", fsname); } /* all filesystems */ filesystems = tst_get_supported_fs_types((const char * const*)skiplist); if (!filesystems[0]) fail_exit("There are no supported filesystems or all skipped"); for (i = 0; filesystems[i]; i++) printf("%s\n", filesystems[i]); return 0; }