1 // SPDX-License-Identifier: GPL-2.0-or-late
2 /*
3 * Copyright (c) International Business Machines Corp., 2004
4 * Copyright (c) Linux Test Project, 2004-2017
5 *
6 * DESCRIPTION
7 * hugeshmget03 - test for ENOSPC error
8 *
9 * HISTORY
10 * 03/2001 - Written by Wayne Boyer
11 * 04/2004 - Updated by Robbie Williamson
12 */
13
14 #include <limits.h>
15 #include "hugetlb.h"
16
17 /*
18 * The MAXIDS value is somewhat arbitrary and may need to be increased
19 * depending on the system being tested.
20 */
21 #define MAXIDS 8192
22 #define PATH_SHMMNI "/proc/sys/kernel/shmmni"
23
24 static size_t shm_size;
25 static int shm_id_1 = -1;
26 static int num_shms;
27 static int shm_id_arr[MAXIDS];
28
29 static long orig_shmmni = -1;
30 static struct tst_option options[] = {
31 {"s:", &nr_opt, "-s num Set the number of the been allocated hugepages"},
32 {NULL, NULL, NULL}
33 };
34
test_hugeshmget(void)35 static void test_hugeshmget(void)
36 {
37 TEST(shmget(IPC_PRIVATE, shm_size,
38 SHM_HUGETLB | IPC_CREAT | IPC_EXCL | SHM_RW));
39 if (TST_RET != -1) {
40 tst_res(TFAIL, "shmget succeeded unexpectedly");
41 return;
42 }
43 if (TST_ERR == ENOSPC)
44 tst_res(TPASS | TTERRNO, "shmget failed as expected");
45 else
46 tst_res(TFAIL | TTERRNO, "shmget failed unexpectedly "
47 "- expect errno=ENOSPC, got");
48 }
49
setup(void)50 static void setup(void)
51 {
52 long hpage_size;
53
54 if (tst_hugepages == 0)
55 tst_brk(TCONF, "No enough hugepages for testing.");
56
57 SAFE_FILE_SCANF(PATH_SHMMNI, "%ld", &orig_shmmni);
58 SAFE_FILE_PRINTF(PATH_SHMMNI, "%ld", tst_hugepages / 2);
59
60 hpage_size = SAFE_READ_MEMINFO("Hugepagesize:") * 1024;
61 shm_size = hpage_size;
62
63 /*
64 * Use a while loop to create the maximum number of memory segments.
65 * If the loop exceeds MAXIDS, then break the test and cleanup.
66 */
67 num_shms = 0;
68 shm_id_1 = shmget(IPC_PRIVATE, shm_size,
69 SHM_HUGETLB | IPC_CREAT | IPC_EXCL | SHM_RW);
70 while (shm_id_1 != -1) {
71 shm_id_arr[num_shms++] = shm_id_1;
72 if (num_shms == MAXIDS)
73 tst_brk(TBROK, "The maximum number of "
74 "shared memory ID's has been reached. "
75 "Please increase the MAXIDS value in "
76 "the test.");
77 shm_id_1 = shmget(IPC_PRIVATE, shm_size,
78 SHM_HUGETLB | IPC_CREAT | IPC_EXCL | SHM_RW);
79 }
80 if (errno != ENOSPC)
81 tst_brk(TBROK | TERRNO, "shmget #setup");
82 }
83
cleanup(void)84 static void cleanup(void)
85 {
86 int i;
87
88 for (i = 0; i < num_shms; i++)
89 rm_shm(shm_id_arr[i]);
90
91 if (orig_shmmni != -1)
92 FILE_PRINTF(PATH_SHMMNI, "%ld", orig_shmmni);
93 }
94
95 static struct tst_test test = {
96 .needs_root = 1,
97 .options = options,
98 .setup = setup,
99 .cleanup = cleanup,
100 .test_all = test_hugeshmget,
101 .request_hugepages = 128,
102 };
103