Skip to content

Commit 4f3ff1f

Browse files
xuyang0410metan-ucw
authored andcommitted
syscalls/ioctl_loop01: Add LO_FLAGS_AUTOCLEAR and LO_FLAGS_PARTSCAN test
For LO_FLAGS_AUTOCLEAR flag, we only check autoclear fieldvalue in sys directory and also get lo_flags by using LOOP_GET_STATUS. For LO_FLAGS_PARTSCAN flag, it is the same as LO_FLAGS_AUTOCLEAR flag. But we also check whether we can scan partition table correctly ie check whether /dev/loopnp1 and /sys/bloclk/loop0/loop0p1 existed. Signed-off-by: Yang Xu <[email protected]> Signed-off-by: Cyril Hrubis <[email protected]>
1 parent b830135 commit 4f3ff1f

File tree

3 files changed

+144
-1
lines changed

3 files changed

+144
-1
lines changed

runtest/syscalls

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,10 +526,11 @@ ioctl03 ioctl03
526526
ioctl04 ioctl04
527527
ioctl05 ioctl05
528528
ioctl06 ioctl06
529-
530529
ioctl07 ioctl07
531530
ioctl08 ioctl08
532531

532+
ioctl_loop01 ioctl_loop01
533+
533534
ioctl_ns01 ioctl_ns01
534535
ioctl_ns02 ioctl_ns02
535536
ioctl_ns03 ioctl_ns03

testcases/kernel/syscalls/ioctl/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
/ioctl06
77
/ioctl07
88
/ioctl08
9+
/ioctl_loop01
910
/ioctl_ns01
1011
/ioctl_ns02
1112
/ioctl_ns03
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
/*
3+
* Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
4+
* Author: Yang Xu <[email protected]>
5+
*
6+
* This is a basic ioctl test about loopdevice.
7+
* It is designed to test LO_FLAGS_AUTOCLEAR and LO_FLAGS_PARTSCAN flag.
8+
*
9+
* For LO_FLAGS_AUTOCLEAR flag, we only check autoclear field value in sys
10+
* directory and also get lo_flags by using LOOP_GET_STATUS.
11+
*
12+
* For LO_FLAGS_PARTSCAN flag, it is the same as LO_FLAGS_AUTOCLEAR flag.
13+
* But we also check whether we can scan partition table correctly ie check
14+
* whether /dev/loopnp1 and /sys/bloclk/loop0/loop0p1 existed.
15+
*/
16+
17+
#include <stdio.h>
18+
#include <unistd.h>
19+
#include <string.h>
20+
#include "lapi/loop.h"
21+
#include "tst_test.h"
22+
23+
static char dev_path[1024], backing_path[1024], backing_file_path[1024];
24+
static int dev_num, attach_flag, dev_fd, parted_sup;
25+
26+
/*
27+
* In drivers/block/loop.c code, set status function doesn't handle
28+
* LO_FLAGS_READ_ONLY flag and ingore it. Only loop_set_fd with read only mode
29+
* file_fd, lo_flags will include LO_FLAGS_READ_ONLY and it's the same for
30+
* LO_FLAGS_DIRECT_IO.
31+
*/
32+
#define SET_FLAGS (LO_FLAGS_AUTOCLEAR | LO_FLAGS_PARTSCAN | LO_FLAGS_READ_ONLY | LO_FLAGS_DIRECT_IO)
33+
#define GET_FLAGS (LO_FLAGS_AUTOCLEAR | LO_FLAGS_PARTSCAN)
34+
35+
static char partscan_path[1024], autoclear_path[1024];
36+
static char loop_partpath[1026], sys_loop_partpath[1026];
37+
38+
static void verify_ioctl_loop(void)
39+
{
40+
int ret;
41+
struct loop_info loopinfo, loopinfoget;
42+
43+
tst_attach_device(dev_path, "test.img");
44+
attach_flag = 1;
45+
46+
TST_ASSERT_INT(partscan_path, 0);
47+
TST_ASSERT_INT(autoclear_path, 0);
48+
TST_ASSERT_STR(backing_path, backing_file_path);
49+
50+
dev_fd = SAFE_OPEN(dev_path, O_RDWR);
51+
memset(&loopinfo, 0, sizeof(loopinfo));
52+
memset(&loopinfoget, 0, sizeof(loopinfoget));
53+
54+
loopinfo.lo_flags = SET_FLAGS;
55+
SAFE_IOCTL(dev_fd, LOOP_SET_STATUS, &loopinfo);
56+
57+
SAFE_IOCTL(dev_fd, LOOP_GET_STATUS, &loopinfoget);
58+
59+
if (loopinfoget.lo_flags & ~GET_FLAGS)
60+
tst_res(TFAIL, "expect %d but got %d", GET_FLAGS, loopinfoget.lo_flags);
61+
else
62+
tst_res(TPASS, "get expected lo_flag %d", loopinfoget.lo_flags);
63+
64+
TST_ASSERT_INT(partscan_path, 1);
65+
TST_ASSERT_INT(autoclear_path, 1);
66+
67+
if (!parted_sup) {
68+
tst_res(TINFO, "Current environment doesn't have parted disk, skip it");
69+
goto detach_device;
70+
}
71+
72+
ret = access(loop_partpath, F_OK);
73+
if (ret == 0)
74+
tst_res(TPASS, "access %s succeeds", loop_partpath);
75+
else
76+
tst_res(TFAIL, "access %s fails", loop_partpath);
77+
78+
ret = access(sys_loop_partpath, F_OK);
79+
if (ret == 0)
80+
tst_res(TPASS, "access %s succeeds", sys_loop_partpath);
81+
else
82+
tst_res(TFAIL, "access %s fails", sys_loop_partpath);
83+
84+
detach_device:
85+
SAFE_CLOSE(dev_fd);
86+
tst_detach_device(dev_path);
87+
attach_flag = 0;
88+
}
89+
90+
static void setup(void)
91+
{
92+
int ret;
93+
const char *const cmd_parted[] = {"parted", "-s", "test.img", "mklabel", "msdos", "mkpart",
94+
"primary", "ext4", "1M", "10M", NULL};
95+
96+
dev_num = tst_find_free_loopdev(dev_path, sizeof(dev_path));
97+
if (dev_num < 0)
98+
tst_brk(TBROK, "Failed to find free loop device");
99+
100+
tst_fill_file("test.img", 0, 1024 * 1024, 10);
101+
102+
ret = tst_cmd(cmd_parted, NULL, NULL, TST_CMD_PASS_RETVAL);
103+
switch (ret) {
104+
case 0:
105+
parted_sup = 1;
106+
break;
107+
case 255:
108+
tst_res(TCONF, "parted binary not installed or failed");
109+
break;
110+
default:
111+
tst_res(TCONF, "parted exited with %i", ret);
112+
break;
113+
}
114+
115+
sprintf(partscan_path, "/sys/block/loop%d/loop/partscan", dev_num);
116+
sprintf(autoclear_path, "/sys/block/loop%d/loop/autoclear", dev_num);
117+
sprintf(backing_path, "/sys/block/loop%d/loop/backing_file", dev_num);
118+
sprintf(sys_loop_partpath, "/sys/block/loop%d/loop%dp1", dev_num, dev_num);
119+
sprintf(backing_file_path, "%s/test.img", tst_get_tmpdir());
120+
sprintf(loop_partpath, "%sp1", dev_path);
121+
}
122+
123+
static void cleanup(void)
124+
{
125+
if (dev_fd > 0)
126+
SAFE_CLOSE(dev_fd);
127+
if (attach_flag)
128+
tst_detach_device(dev_path);
129+
}
130+
131+
static struct tst_test test = {
132+
.setup = setup,
133+
.cleanup = cleanup,
134+
.test_all = verify_ioctl_loop,
135+
.needs_root = 1,
136+
.needs_drivers = (const char *const []) {
137+
"loop",
138+
NULL
139+
},
140+
.needs_tmpdir = 1,
141+
};

0 commit comments

Comments
 (0)