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 * extra_opt)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 *extra_opt)
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 
34 	if (!dev) {
35 		tst_brkm(TBROK, cleanup_fn,
36 			 "%s:%d: No device specified", file, lineno);
37 		return;
38 	}
39 
40 	if (!fs_type) {
41 		tst_brkm(TBROK, cleanup_fn,
42 			 "%s:%d: No fs_type specified", file, lineno);
43 		return;
44 	}
45 
46 	snprintf(mkfs, sizeof(mkfs), "mkfs.%s", fs_type);
47 
48 	if (fs_opts) {
49 		for (i = 0; fs_opts[i]; i++) {
50 			argv[pos++] = fs_opts[i];
51 
52 			if (pos + 2 > OPTS_MAX) {
53 				tst_brkm(TBROK, cleanup_fn,
54 				         "%s:%d: Too much mkfs options",
55 					 file, lineno);
56 				return;
57 			}
58 
59 			if (i)
60 				strcat(fs_opts_str, " ");
61 			strcat(fs_opts_str, fs_opts[i]);
62 		}
63 	}
64 
65 	argv[pos++] = dev;
66 
67 	if (extra_opt) {
68 		argv[pos++] = extra_opt;
69 
70 		if (pos + 1 > OPTS_MAX) {
71 			tst_brkm(TBROK, cleanup_fn,
72 			         "%s:%d: Too much mkfs options", file, lineno);
73 			return;
74 		}
75 	}
76 
77 	argv[pos] = NULL;
78 
79 	if (tst_clear_device(dev))
80 		tst_brkm(TBROK, cleanup_fn, "tst_clear_device() failed");
81 
82 	tst_resm(TINFO, "Formatting %s with %s opts='%s' extra opts='%s'",
83 	         dev, fs_type, fs_opts_str, extra_opt ? extra_opt : "");
84 	ret = tst_run_cmd(cleanup_fn, argv, "/dev/null", NULL, 1);
85 
86 	switch (ret) {
87 	case 0:
88 	break;
89 	case 255:
90 		tst_brkm(TCONF, cleanup_fn,
91 			 "%s:%d: %s not found in $PATH", file, lineno, mkfs);
92 	default:
93 		tst_brkm(TBROK, cleanup_fn,
94 			 "%s:%d: %s failed with %i", mkfs, ret, file, lineno);
95 	}
96 }
97 
tst_dev_fs_type(void)98 const char *tst_dev_fs_type(void)
99 {
100 	const char *fs_type;
101 
102 	fs_type = getenv("LTP_DEV_FS_TYPE");
103 
104 	if (fs_type)
105 		return fs_type;
106 
107 	return DEFAULT_FS_TYPE;
108 }
109