1 // SPDX-License-Identifier: GPL-2.0-or-later
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;
test_hugeshmget(void)30 static void test_hugeshmget(void)
31 {
32 TEST(shmget(IPC_PRIVATE, shm_size,
33 SHM_HUGETLB | IPC_CREAT | IPC_EXCL | SHM_RW));
34 if (TST_RET != -1) {
35 tst_res(TFAIL, "shmget succeeded unexpectedly");
36 return;
37 }
38 if (TST_ERR == ENOSPC)
39 tst_res(TPASS | TTERRNO, "shmget failed as expected");
40 else
41 tst_res(TFAIL | TTERRNO, "shmget failed unexpectedly "
42 "- expect errno=ENOSPC, got");
43 }
44
setup(void)45 static void setup(void)
46 {
47 long hpage_size;
48
49 if (tst_hugepages == 0)
50 tst_brk(TCONF, "No enough hugepages for testing.");
51
52 SAFE_FILE_SCANF(PATH_SHMMNI, "%ld", &orig_shmmni);
53 SAFE_FILE_PRINTF(PATH_SHMMNI, "%ld", tst_hugepages / 2);
54
55 hpage_size = SAFE_READ_MEMINFO("Hugepagesize:") * 1024;
56 shm_size = hpage_size;
57
58 /*
59 * Use a while loop to create the maximum number of memory segments.
60 * If the loop exceeds MAXIDS, then break the test and cleanup.
61 */
62 num_shms = 0;
63 shm_id_1 = shmget(IPC_PRIVATE, shm_size,
64 SHM_HUGETLB | IPC_CREAT | IPC_EXCL | SHM_RW);
65 while (shm_id_1 != -1) {
66 shm_id_arr[num_shms++] = shm_id_1;
67 if (num_shms == MAXIDS)
68 tst_brk(TBROK, "The maximum number of "
69 "shared memory ID's has been reached. "
70 "Please increase the MAXIDS value in "
71 "the test.");
72 shm_id_1 = shmget(IPC_PRIVATE, shm_size,
73 SHM_HUGETLB | IPC_CREAT | IPC_EXCL | SHM_RW);
74 }
75 if (errno != ENOSPC)
76 tst_brk(TBROK | TERRNO, "shmget #setup");
77 }
78
cleanup(void)79 static void cleanup(void)
80 {
81 int i;
82
83 for (i = 0; i < num_shms; i++)
84 rm_shm(shm_id_arr[i]);
85
86 if (orig_shmmni != -1)
87 SAFE_FILE_PRINTF(PATH_SHMMNI, "%ld", orig_shmmni);
88 }
89
90 static struct tst_test test = {
91 .needs_root = 1,
92 .options = (struct tst_option[]) {
93 {"s:", &nr_opt, "Set the number of the been allocated hugepages"},
94 {}
95 },
96 .setup = setup,
97 .cleanup = cleanup,
98 .test_all = test_hugeshmget,
99 .hugepages = {128, TST_REQUEST},
100 };
101