blob: 0d55d0a641970b36d0136cfc72ee57c9a5e4f89d [file] [log] [blame]
DAN LI6582c372013-07-17 14:36:34 +08001/*
2 * Copyright (c) 2013 Fujitsu Ltd.
3 * Author: DAN LI <li.dan@cn.fujitsu.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 *
17 */
18
19/*
20 * DESCRIPTION
21 * Test for feature MS_MOVE of mount(2).
22 * "Move an existing mount point to the new location."
23 */
24
25#include <errno.h>
26#include <sys/mount.h>
27#include <unistd.h>
28#include <fcntl.h>
29
30#include "test.h"
DAN LI6582c372013-07-17 14:36:34 +080031#include "safe_macros.h"
32
DAN LI94469ba2013-07-31 09:52:20 +080033#ifndef MS_MOVE
34#define MS_MOVE 8192
35#endif
36
37#ifndef MS_PRIVATE
38#define MS_PRIVATE (1 << 18)
39#endif
40
DAN LI6582c372013-07-17 14:36:34 +080041#define MNTPOINT_SRC "mnt_src"
42#define MNTPOINT_DES "mnt_des"
43#define LINELENGTH 256
44#define DIR_MODE (S_IRWXU | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP)
45
46static int ismount(char *mntpoint);
47static void setup(void);
48static void cleanup(void);
DAN LI6582c372013-07-17 14:36:34 +080049
50char *TCID = "mount06";
51int TST_TOTAL = 1;
52
Cyril Hrubise7eb3f02014-08-13 14:44:02 +020053static const char *fs_type;
54static const char *device;
DAN LI6582c372013-07-17 14:36:34 +080055static char path_name[PATH_MAX];
56static char mntpoint_src[PATH_MAX];
57static char mntpoint_des[PATH_MAX];
Cyril Hrubise7eb3f02014-08-13 14:44:02 +020058static int mount_flag;
DAN LI6582c372013-07-17 14:36:34 +080059
60int main(int argc, char *argv[])
61{
62 int lc;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +020063 const char *msg;
DAN LI6582c372013-07-17 14:36:34 +080064
Cyril Hrubise7eb3f02014-08-13 14:44:02 +020065 msg = parse_opts(argc, argv, NULL, NULL);
DAN LI6582c372013-07-17 14:36:34 +080066 if (msg != NULL)
67 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
68
DAN LI6582c372013-07-17 14:36:34 +080069 setup();
70
71 for (lc = 0; TEST_LOOPING(lc); lc++) {
72
73 tst_count = 0;
74
Cyril Hrubise7eb3f02014-08-13 14:44:02 +020075 if (mount(device, mntpoint_src, fs_type, 0, NULL) == -1)
DAN LI6582c372013-07-17 14:36:34 +080076 tst_brkm(TBROK | TERRNO, cleanup, "mount %s failed",
77 mntpoint_src);
78
Cyril Hrubise7eb3f02014-08-13 14:44:02 +020079 TEST(mount(mntpoint_src, mntpoint_des, fs_type, MS_MOVE, NULL));
DAN LI6582c372013-07-17 14:36:34 +080080
81 if (TEST_RETURN != 0) {
82 tst_resm(TFAIL | TTERRNO, "mount(2) failed");
83 } else {
84
85 if (!ismount(mntpoint_src) && ismount(mntpoint_des))
86 tst_resm(TPASS, "move mount is ok");
87 else
88 tst_resm(TFAIL, "move mount does not work");
89
Cyril Hrubisc60a2302015-01-29 16:28:24 +010090 TEST(tst_umount(mntpoint_des));
DAN LI6582c372013-07-17 14:36:34 +080091 if (TEST_RETURN != 0)
92 tst_brkm(TBROK | TTERRNO, cleanup,
93 "umount(2) failed");
94 }
95 }
DAN LI6582c372013-07-17 14:36:34 +080096
Cyril Hrubise7eb3f02014-08-13 14:44:02 +020097 cleanup();
DAN LI6582c372013-07-17 14:36:34 +080098 tst_exit();
99}
100
101int ismount(char *mntpoint)
102{
103 int ret = 0;
104 FILE *file;
105 char line[LINELENGTH];
106
107 file = fopen("/proc/mounts", "r");
108 if (file == NULL)
109 tst_brkm(TFAIL | TERRNO, NULL, "Open /proc/mounts failed");
110
111 while (fgets(line, LINELENGTH, file) != NULL) {
112 if (strstr(line, mntpoint) != NULL) {
113 ret = 1;
114 break;
115 }
116 }
117 fclose(file);
118 return ret;
119}
120
Cyril Hrubise7eb3f02014-08-13 14:44:02 +0200121static void setup(void)
DAN LI6582c372013-07-17 14:36:34 +0800122{
123 tst_require_root(NULL);
DAN LI6582c372013-07-17 14:36:34 +0800124
125 tst_sig(NOFORK, DEF_HANDLER, cleanup);
126
127 tst_tmpdir();
128
Cyril Hrubise7eb3f02014-08-13 14:44:02 +0200129 fs_type = tst_dev_fs_type();
130 device = tst_acquire_device(cleanup);
131
132 if (!device)
133 tst_brkm(TCONF, cleanup, "Failed to obtain block device");
134
135 tst_mkfs(cleanup, device, fs_type, NULL);
136
DAN LI6582c372013-07-17 14:36:34 +0800137 if (getcwd(path_name, sizeof(path_name)) == NULL)
138 tst_brkm(TBROK, cleanup, "getcwd failed");
139
140 /*
141 * Turn current dir into a private mount point being a parent
142 * mount which is required by move mount.
143 */
144 if (mount(path_name, path_name, "none", MS_BIND, NULL) == -1)
145 tst_brkm(TBROK | TERRNO, cleanup, "bind mount failed");
146
Cyril Hrubise7eb3f02014-08-13 14:44:02 +0200147 mount_flag = 1;
148
DAN LI6582c372013-07-17 14:36:34 +0800149 if (mount("none", path_name, "none", MS_PRIVATE, NULL) == -1)
150 tst_brkm(TBROK | TERRNO, cleanup, "mount private failed");
151
152 snprintf(mntpoint_src, PATH_MAX, "%s/%s", path_name, MNTPOINT_SRC);
153 snprintf(mntpoint_des, PATH_MAX, "%s/%s", path_name, MNTPOINT_DES);
154
155 SAFE_MKDIR(cleanup, mntpoint_src, DIR_MODE);
156 SAFE_MKDIR(cleanup, mntpoint_des, DIR_MODE);
157
158 TEST_PAUSE;
159}
160
Cyril Hrubise7eb3f02014-08-13 14:44:02 +0200161static void cleanup(void)
DAN LI6582c372013-07-17 14:36:34 +0800162{
Cyril Hrubisc60a2302015-01-29 16:28:24 +0100163 if (mount_flag && tst_umount(path_name) != 0)
Cyril Hrubise7eb3f02014-08-13 14:44:02 +0200164 tst_resm(TWARN | TERRNO, "umount(2) %s failed", path_name);
DAN LI6582c372013-07-17 14:36:34 +0800165
Cyril Hrubise7eb3f02014-08-13 14:44:02 +0200166 if (device)
167 tst_release_device(NULL, device);
DAN LI6582c372013-07-17 14:36:34 +0800168
Cyril Hrubise7eb3f02014-08-13 14:44:02 +0200169 tst_rmdir();
DAN LI6582c372013-07-17 14:36:34 +0800170}