1 #include "mach_vm_tests.h"
3 T_GLOBAL_META(T_META_NAMESPACE("xnu.vm"));
8 spawn_process(char *action
, char *serviceName
, char *extraArg
,
9 mach_port_t
*server_Port
, pid_t
*serverPid
, boolean_t use4k
);
11 static void mach_client(void);
13 mach_port_t serverPort
;
14 static pid_t serverPid
;
16 boolean_t debug
= TRUE
;
19 spawn_process(char *action
, char *serviceName
, char *extraArg
,
20 mach_port_t
*server_Port
, pid_t
*server_Pid
, boolean_t use4k
)
22 char buffer
[PATH_MAX
];
26 int r
= proc_pidpath(getpid(), buffer
, sizeof(buffer
));
27 T_ASSERT_NE(r
, -1, "proc_pidpath");
28 r
= (int)strlcat(buffer
, "_server", sizeof(buffer
));
29 T_ASSERT_LT(r
, (int)sizeof(buffer
), "strlcat");
33 size_t supported_size
= sizeof(supported
);
35 r
= sysctlbyname("debug.vm_mixed_pagesize_supported", &supported
, &supported_size
, NULL
, 0);
36 if (r
== 0 && supported
) {
37 T_LOG("Using %s to spawn process with 4k", VM_SPAWN_TOOL
);
38 argv
[arg_index
++] = VM_SPAWN_TOOL
;
41 * We didnt find debug.vm.mixed_page.supported OR its set to 0.
44 T_SKIP("Hardware doesn't support 4K pages, skipping test...");
48 argv
[arg_index
++] = (char *)&buffer
[0];
49 argv
[arg_index
++] = (char *)action
;
50 argv
[arg_index
++] = (char *)serviceName
;
51 argv
[arg_index
++] = (char *)extraArg
;
52 argv
[arg_index
++] = NULL
;
54 printf("posix_spawn with argv: ");
55 for (r
= 0; r
<= arg_index
; r
++) {
56 printf("%s ", argv
[r
]);
60 T_LOG("Spawning %s process(%s) with service name %s at %s\n", action
, buffer
, serviceName
, buffer
);
63 posix_spawn_file_actions_t actions
;
64 posix_spawn_file_actions_init(&actions
);
66 T_ASSERT_POSIX_ZERO(posix_spawn(&pid
, buffer
, &actions
, NULL
, argv
, environ
), "spawn %s", serviceName
);
67 posix_spawn_file_actions_destroy(&actions
);
70 mach_port_t servicePort
;
72 const int kMaxAttempts
= 10;
75 ret
= bootstrap_look_up(bootstrap_port
, serviceName
, &servicePort
);
77 } while (ret
== BOOTSTRAP_UNKNOWN_SERVICE
&& attempts
< kMaxAttempts
);
79 if (ret
!= KERN_SUCCESS
) {
80 printf("ERROR: Failed bootstrap lookup for process with mach service name '%s': (%d) %s\n", serviceName
, ret
, mach_error_string(ret
));
84 T_FAIL("Failed bootstrap lookup for process with mach service");
87 *server_Port
= servicePort
;
89 T_LOG("Server pid=%d port 0x%x", pid
, servicePort
);
98 mach_port_t replyPort
;
99 T_ASSERT_POSIX_ZERO(mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE
, &replyPort
), "create recieve port");
100 T_ASSERT_POSIX_ZERO(mach_port_insert_right(mach_task_self(), replyPort
, replyPort
, MACH_MSG_TYPE_MAKE_SEND
), "insert send port");
102 ipc_message_t message
;
103 bzero(&message
, sizeof(message
));
104 message
.header
.msgh_id
= 1;
106 message
.header
.msgh_bits
= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND
, MACH_MSG_TYPE_COPY_SEND
);
107 message
.header
.msgh_remote_port
= serverPort
;
108 message
.header
.msgh_local_port
= replyPort
;
109 message
.header
.msgh_size
= sizeof(message
);
111 /* reply creation is not necessary in this case.
112 * mach_msg_size_t replySize = sizeof(ipc_message_t) + sizeof(mach_msg_trailer_t) + 64;
113 * ipc_message_t *reply = calloc(1, replySize);
115 T_LOG("sending message to %d of size %u", message
.header
.msgh_remote_port
, message
.header
.msgh_size
);
116 kern_return_t ret
= mach_msg(&message
.header
, MACH_SEND_MSG
, message
.header
.msgh_size
, 0, MACH_PORT_NULL
, MACH_MSG_TIMEOUT_NONE
, MACH_PORT_NULL
);
117 T_ASSERT_MACH_SUCCESS(ret
, "mach_msg to serverProcess");
118 mach_vm_client(replyPort
);
119 T_LOG("Sending SIGKILL to server(%d)", serverPid
);
120 kill(serverPid
, SIGKILL
);
123 T_DECL(memory_share_tests
,
124 "test vm memory sharing between client and server process with different process PAGE_SIZE",
127 boolean_t use4k
= FALSE
;
128 char serviceName
[64];
130 struct sigaction action
= {
131 .sa_handler
= SIG_IGN
,
132 .sa_flags
= SA_NOCLDWAIT
134 sigaction(SIGCHLD
, &action
, NULL
);
136 if (getenv("USE4K")) {
140 if (getenv("QUIET")) {
144 T_LOG("running with use4k=%d debug=%d", use4k
, (int)debug
);
146 strcpy(serviceName
, MACH_VM_TEST_SERVICE_NAME
);
148 spawn_process("machserver", serviceName
, NULL
, &serverPort
, &serverPid
, use4k
);
152 T_DECL_REF(memory_share_tests_4k
, memory_share_tests
, "vm memory sharing with 4k processes",
153 T_META_ENVVAR("USE4K=YES"),