1 /*
2  * Copyright (c) 2013-2016 Cyril Hrubis <chrubis@suse.cz>
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "test.h"
19 #include "ltp_priv.h"
20 #include "tst_mkfs.h"
21 #include "tst_device.h"
22 
23 #define OPTS_MAX 32
24 
tst_mkfs_(const char * file,const int lineno,void (cleanup_fn)(void),const char * dev,const char * fs_type,const char * const fs_opts[],const char * const extra_opts[])25 void tst_mkfs_(const char *file, const int lineno, void (cleanup_fn)(void),
26 	       const char *dev, const char *fs_type,
27 	       const char *const fs_opts[], const char *const extra_opts[])
28 {
29 	int i, pos = 1, ret;
30 	char mkfs[64];
31 	const char *argv[OPTS_MAX] = {mkfs};
32 	char fs_opts_str[1024] = "";
33 	char extra_opts_str[1024] = "";
34 
35 	if (!dev) {
36 		tst_brkm(TBROK, cleanup_fn,
37 			 "%s:%d: No device specified", file, lineno);
38 		return;
39 	}
40 
41 	if (!fs_type) {
42 		tst_brkm(TBROK, cleanup_fn,
43 			 "%s:%d: No fs_type specified", file, lineno);
44 		return;
45 	}
46 
47 	snprintf(mkfs, sizeof(mkfs), "mkfs.%s", fs_type);
48 
49 	if (fs_opts) {
50 		for (i = 0; fs_opts[i]; i++) {
51 			argv[pos++] = fs_opts[i];
52 
53 			if (pos + 2 > OPTS_MAX) {
54 				tst_brkm(TBROK, cleanup_fn,
55 				         "%s:%d: Too much mkfs options",
56 					 file, lineno);
57 				return;
58 			}
59 
60 			if (i)
61 				strcat(fs_opts_str, " ");
62 			strcat(fs_opts_str, fs_opts[i]);
63 		}
64 	}
65 
66 	argv[pos++] = dev;
67 
68 	if (extra_opts) {
69 		for (i = 0; extra_opts[i]; i++) {
70 			argv[pos++] = extra_opts[i];
71 
72 			if (pos + 1 > OPTS_MAX) {
73 				tst_brkm(TBROK, cleanup_fn,
74 				         "%s:%d: Too much mkfs options", file, lineno);
75 				return;
76 			}
77 
78 			if (i)
79 				strcat(extra_opts_str, " ");
80 			strcat(extra_opts_str, extra_opts[i]);
81 		}
82 	}
83 
84 	argv[pos] = NULL;
85 
86 	if (tst_clear_device(dev))
87 		tst_brkm(TBROK, cleanup_fn, "tst_clear_device() failed");
88 
89 	tst_resm(TINFO, "Formatting %s with %s opts='%s' extra opts='%s'",
90 	         dev, fs_type, fs_opts_str, extra_opts_str);
91 	ret = tst_run_cmd(cleanup_fn, argv, "/dev/null", NULL, 1);
92 
93 	switch (ret) {
94 	case 0:
95 	break;
96 	case 255:
97 		tst_brkm(TCONF, cleanup_fn,
98 			 "%s:%d: %s not found in $PATH", file, lineno, mkfs);
99 	default:
100 		tst_brkm(TBROK, cleanup_fn,
101 			 "%s:%d: %s failed with %i", file, lineno, mkfs, ret);
102 	}
103 }
104 
tst_dev_fs_type(void)105 const char *tst_dev_fs_type(void)
106 {
107 	const char *fs_type;
108 
109 	fs_type = getenv("LTP_DEV_FS_TYPE");
110 
111 	if (fs_type)
112 		return fs_type;
113 
114 	return DEFAULT_FS_TYPE;
115 }
116