Print this page
make: unifdef for other OSes (undefined)
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/make/bin/dist.cc
+++ new/usr/src/cmd/make/bin/dist.cc
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 #ifdef DISTRIBUTED
27 27 /*
28 28 * dist.cc
29 29 *
30 30 * Deal with the distributed processing
31 31 */
32 32
33 33 #include <avo/err.h>
34 34 #include <avo/find_dir.h>
↓ open down ↓ |
34 lines elided |
↑ open up ↑ |
35 35 #include <avo/util.h>
36 36 #include <dm/Avo_AcknowledgeMsg.h>
37 37 #include <dm/Avo_DoJobMsg.h>
38 38 #include <dm/Avo_JobResultMsg.h>
39 39 #include <mk/defs.h>
40 40 #include <mksh/misc.h> /* getmem() */
41 41 #include <rw/pstream.h>
42 42 #include <rw/queuecol.h>
43 43 #include <rw/xdrstrea.h>
44 44 #include <signal.h>
45 -#ifdef linux
46 -#include <sstream>
47 -using namespace std;
48 -#else
49 45 #include <strstream.h>
50 -#endif
51 46 #include <sys/stat.h> /* stat() */
52 47 #include <sys/types.h>
53 48 #include <sys/wait.h>
54 49 #include <unistd.h>
55 50 #include <errno.h>
56 51
57 52 /*
58 53 * Defined macros
59 54 */
60 55
61 56 #define AVO_BLOCK_INTERUPTS sigfillset(&newset) ; \
62 57 sigprocmask(SIG_SETMASK, &newset, &oldset)
63 58
64 59 #define AVO_UNBLOCK_INTERUPTS \
65 60 sigprocmask(SIG_SETMASK, &oldset, &newset)
66 61
67 62
68 63 /*
69 64 * typedefs & structs
70 65 */
71 66
72 67 /*
73 68 * Static variables
74 69 */
75 70 int dmake_ifd;
76 71 FILE* dmake_ifp;
77 72 XDR xdrs_in;
78 73
79 74 int dmake_ofd;
80 75 FILE* dmake_ofp;
81 76 XDR xdrs_out;
82 77
83 78 // These instances are required for the RWfactory.
84 79 static Avo_JobResultMsg dummyJobResultMsg;
85 80 static Avo_AcknowledgeMsg dummyAcknowledgeMsg;
86 81 static int firstAcknowledgeReceived = 0;
87 82
88 83 int rxmPid = 0;
89 84
90 85 /*
91 86 * File table of contents
92 87 */
93 88 static void set_dmake_env_vars(void);
94 89
95 90 /*
96 91 * void
97 92 * startup_rxm(void)
98 93 *
99 94 * When startup_rxm() is called, read_command_options() and
100 95 * read_files_and_state() have already been read, so DMake
101 96 * will now know what options to pass to rxm.
102 97 *
103 98 * rxm
104 99 * [ -k ] [ -n ]
105 100 * [ -c <dmake_rcfile> ]
106 101 * [ -g <dmake_group> ]
107 102 * [ -j <dmake_max_jobs> ]
108 103 * [ -m <dmake_mode> ]
109 104 * [ -o <dmake_odir> ]
110 105 * <read_fd> <write_fd>
111 106 *
112 107 * rxm will, among other things, read the rc file.
113 108 *
114 109 */
115 110 void
116 111 startup_rxm(void)
117 112 {
118 113 Name dmake_name;
119 114 Name dmake_value;
120 115 Avo_err *find_run_dir_err;
121 116 int pipe1[2], pipe2[2];
122 117 Property prop;
123 118 char *run_dir;
124 119 char rxm_command[MAXPATHLEN];
125 120 int rxm_debug = 0;
126 121
127 122 int length;
128 123 char * env;
129 124
130 125 firstAcknowledgeReceived = 0;
131 126 /*
132 127 * Create two pipes, one for dmake->rxm, and one for rxm->dmake.
133 128 * pipe1 is dmake->rxm,
134 129 * pipe2 is rxm->dmake.
135 130 */
136 131 if ((pipe(pipe1) < 0) || (pipe(pipe2) < 0)) {
137 132 fatal(catgets(catd, 1, 245, "pipe() failed: %s"), errmsg(errno));
138 133 }
139 134
140 135 set_dmake_env_vars();
141 136
142 137 if ((rxmPid = fork()) < 0) { /* error */
143 138 fatal(catgets(catd, 1, 246, "fork() failed: %s"), errmsg(errno));
144 139 } else if (rxmPid > 0) { /* parent, dmake */
145 140 dmake_ofd = pipe1[1]; // write side of pipe
146 141 if (!(dmake_ofp = fdopen(dmake_ofd, "a"))) {
147 142 fatal(catgets(catd, 1, 247, "fdopen() failed: %s"), errmsg(errno));
148 143 }
149 144 xdrstdio_create(&xdrs_out, dmake_ofp, XDR_ENCODE);
150 145
151 146 dmake_ifd = pipe2[0]; // read side of pipe
152 147 if (!(dmake_ifp = fdopen(dmake_ifd, "r"))) {
153 148 fatal(catgets(catd, 1, 248, "fdopen() failed: %s"), errmsg(errno));
154 149 }
155 150 xdrstdio_create(&xdrs_in, dmake_ifp, XDR_DECODE);
156 151
157 152 close(pipe1[0]); // read side
158 153 close(pipe2[1]); // write side
159 154 } else { /* child, rxm */
160 155 close(pipe1[1]); // write side
161 156 close(pipe2[0]); // read side
162 157
163 158 /* Find the run directory of dmake, for rxm. */
164 159 find_run_dir_err = avo_find_run_dir(&run_dir);
165 160 if (find_run_dir_err) {
166 161 delete find_run_dir_err;
167 162 /* Use the path to find rxm. */
168 163 (void) sprintf(rxm_command, NOCATGETS("rxm"));
169 164 } else {
170 165 /* Use the run dir of dmake for rxm. */
171 166 (void) sprintf(rxm_command, NOCATGETS("%s/rxm"), run_dir);
172 167 }
173 168
174 169 if (continue_after_error) {
175 170 (void) strcat(rxm_command, NOCATGETS(" -k"));
176 171 }
177 172 if (do_not_exec_rule) {
178 173 (void) strcat(rxm_command, NOCATGETS(" -n"));
179 174 }
180 175 if (rxm_debug) {
181 176 (void) strcat(rxm_command, NOCATGETS(" -S"));
182 177 }
183 178 if (send_mtool_msgs) {
184 179 (void) sprintf(&rxm_command[strlen(rxm_command)],
185 180 NOCATGETS(" -O %d"),
186 181 mtool_msgs_fd);
187 182 }
188 183 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_RCFILE"));
189 184 dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
190 185 if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
191 186 ((dmake_value = prop->body.macro.value) != NULL)) {
192 187 (void) sprintf(&rxm_command[strlen(rxm_command)],
193 188 NOCATGETS(" -c %s"),
194 189 dmake_value->string_mb);
195 190 } else {
196 191 length = 2 + strlen(NOCATGETS("DMAKE_RCFILE"));
197 192 env = getmem(length);
198 193 (void) sprintf(env,
199 194 "%s=",
200 195 NOCATGETS("DMAKE_RCFILE"));
201 196 (void) putenv(env);
202 197 }
203 198 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_GROUP"));
204 199 dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
205 200 if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
206 201 ((dmake_value = prop->body.macro.value) != NULL)) {
207 202 (void) sprintf(&rxm_command[strlen(rxm_command)],
208 203 NOCATGETS(" -g %s"),
209 204 dmake_value->string_mb);
210 205 } else {
211 206 length = 2 + strlen(NOCATGETS("DMAKE_GROUP"));
212 207 env = getmem(length);
213 208 (void) sprintf(env,
214 209 "%s=",
215 210 NOCATGETS("DMAKE_GROUP"));
216 211 (void) putenv(env);
217 212 }
218 213 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MAX_JOBS"));
219 214 dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
220 215 if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
221 216 ((dmake_value = prop->body.macro.value) != NULL)) {
222 217 (void) sprintf(&rxm_command[strlen(rxm_command)],
223 218 NOCATGETS(" -j %s"),
224 219 dmake_value->string_mb);
225 220 } else {
226 221 length = 2 + strlen(NOCATGETS("DMAKE_MAX_JOBS"));
227 222 env = getmem(length);
228 223 (void) sprintf(env,
229 224 "%s=",
230 225 NOCATGETS("DMAKE_MAX_JOBS"));
231 226 (void) putenv(env);
232 227 }
233 228 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_MODE"));
234 229 dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
235 230 if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
236 231 ((dmake_value = prop->body.macro.value) != NULL)) {
237 232 (void) sprintf(&rxm_command[strlen(rxm_command)],
238 233 NOCATGETS(" -m %s"),
239 234 dmake_value->string_mb);
240 235 } else {
241 236 length = 2 + strlen(NOCATGETS("DMAKE_MODE"));
242 237 env = getmem(length);
243 238 (void) sprintf(env,
244 239 "%s=",
245 240 NOCATGETS("DMAKE_MODE"));
246 241 (void) putenv(env);
247 242 }
248 243 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_ODIR"));
249 244 dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
250 245 if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
251 246 ((dmake_value = prop->body.macro.value) != NULL)) {
252 247 (void) sprintf(&rxm_command[strlen(rxm_command)],
253 248 NOCATGETS(" -o %s"),
254 249 dmake_value->string_mb);
255 250 } else {
256 251 length = 2 + strlen(NOCATGETS("DMAKE_ODIR"));
↓ open down ↓ |
196 lines elided |
↑ open up ↑ |
257 252 env = getmem(length);
258 253 (void) sprintf(env,
259 254 "%s=",
260 255 NOCATGETS("DMAKE_ODIR"));
261 256 (void) putenv(env);
262 257 }
263 258
264 259 (void) sprintf(&rxm_command[strlen(rxm_command)],
265 260 NOCATGETS(" %d %d"),
266 261 pipe1[0], pipe2[1]);
267 -#ifdef linux
268 - execl(NOCATGETS("/bin/sh"),
269 -#else
270 262 execl(NOCATGETS("/usr/bin/sh"),
271 -#endif
272 263 NOCATGETS("sh"),
273 264 NOCATGETS("-c"),
274 265 rxm_command,
275 266 (char *)NULL);
276 267 _exit(127);
277 268 }
278 269 }
279 270
280 271 /*
281 272 * static void
282 273 * set_dmake_env_vars()
283 274 *
284 275 * Sets the DMAKE_* environment variables for rxm and rxs.
285 276 * DMAKE_PWD
286 277 * DMAKE_NPWD
287 278 * DMAKE_UMASK
288 279 * DMAKE_SHELL
289 280 */
290 281 static void
291 282 set_dmake_env_vars()
292 283 {
293 284 char *current_netpath;
294 285 char *current_path;
295 286 static char *env;
296 287 int length;
297 288 char netpath[MAXPATHLEN];
298 289 mode_t um;
299 290 char um_buf[MAXPATHLEN];
300 291 Name dmake_name;
301 292 Name dmake_value;
302 293 Property prop;
303 294
304 295 #ifdef REDIRECT_ERR
305 296 /* Set __DMAKE_REDIRECT_STDERR */
306 297 length = 2 + strlen(NOCATGETS("__DMAKE_REDIRECT_STDERR")) + 1;
307 298 env = getmem(length);
308 299 (void) sprintf(env,
309 300 "%s=%s",
310 301 NOCATGETS("__DMAKE_REDIRECT_STDERR"),
311 302 out_err_same ? NOCATGETS("0") : NOCATGETS("1"));
312 303 (void) putenv(env);
313 304 #endif
314 305
315 306 /* Set DMAKE_PWD to the current working directory */
316 307 current_path = get_current_path();
317 308 length = 2 + strlen(NOCATGETS("DMAKE_PWD")) + strlen(current_path);
318 309 env = getmem(length);
319 310 (void) sprintf(env,
320 311 "%s=%s",
321 312 NOCATGETS("DMAKE_PWD"),
322 313 current_path);
323 314 (void) putenv(env);
324 315
325 316 /* Set DMAKE_NPWD to machine:pathname */
326 317 if (avo_path_to_netpath(current_path, netpath)) {
327 318 current_netpath = netpath;
328 319 } else {
329 320 current_netpath = current_path;
330 321 }
331 322 length = 2 + strlen(NOCATGETS("DMAKE_NPWD")) + strlen(current_netpath);
332 323 env = getmem(length);
333 324 (void) sprintf(env,
334 325 "%s=%s",
335 326 NOCATGETS("DMAKE_NPWD"),
336 327 current_netpath);
337 328 (void) putenv(env);
338 329
339 330 /* Set DMAKE_UMASK to the value of umask */
340 331 um = umask(0);
341 332 umask(um);
342 333 (void) sprintf(um_buf, NOCATGETS("%ul"), um);
343 334 length = 2 + strlen(NOCATGETS("DMAKE_UMASK")) + strlen(um_buf);
344 335 env = getmem(length);
345 336 (void) sprintf(env,
346 337 "%s=%s",
347 338 NOCATGETS("DMAKE_UMASK"),
348 339 um_buf);
349 340 (void) putenv(env);
350 341
351 342 if (((prop = get_prop(shell_name->prop, macro_prop)) != NULL) &&
352 343 ((dmake_value = prop->body.macro.value) != NULL)) {
353 344 length = 2 + strlen(NOCATGETS("DMAKE_SHELL")) +
354 345 strlen(dmake_value->string_mb);
355 346 env = getmem(length);
356 347 (void) sprintf(env,
357 348 "%s=%s",
358 349 NOCATGETS("DMAKE_SHELL"),
359 350 dmake_value->string_mb);
360 351 (void) putenv(env);
361 352 }
362 353 MBSTOWCS(wcs_buffer, NOCATGETS("DMAKE_OUTPUT_MODE"));
363 354 dmake_name = GETNAME(wcs_buffer, FIND_LENGTH);
364 355 if (((prop = get_prop(dmake_name->prop, macro_prop)) != NULL) &&
365 356 ((dmake_value = prop->body.macro.value) != NULL)) {
366 357 length = 2 + strlen(NOCATGETS("DMAKE_OUTPUT_MODE")) +
367 358 strlen(dmake_value->string_mb);
368 359 env = getmem(length);
369 360 (void) sprintf(env,
370 361 "%s=%s",
371 362 NOCATGETS("DMAKE_OUTPUT_MODE"),
372 363 dmake_value->string_mb);
373 364 (void) putenv(env);
374 365 }
375 366 }
376 367
377 368 /*
378 369 * void
379 370 * distribute_rxm(Avo_DoJobMsg *dmake_job_msg)
380 371 *
381 372 * Write the DMake rule to be distributed down the pipe to rxm.
382 373 *
383 374 */
384 375 void
385 376 distribute_rxm(Avo_DoJobMsg *dmake_job_msg)
386 377 {
387 378 /* Add all dynamic env vars to the dmake_job_msg. */
388 379 setvar_envvar(dmake_job_msg);
389 380
390 381 /*
391 382 * Copying dosys()...
392 383 * Stat .make.state to see if we'll need to reread it later
393 384 */
394 385 make_state->stat.time = file_no_time;
395 386 (void)exists(make_state);
396 387 make_state_before = make_state->stat.time;
397 388
398 389 // Wait for the first Acknowledge message from the rxm process
399 390 // before sending the first message.
400 391 if (!firstAcknowledgeReceived) {
401 392 firstAcknowledgeReceived++;
402 393 Avo_AcknowledgeMsg *msg = getAcknowledgeMsg();
403 394 if (msg) {
404 395 delete msg;
405 396 }
406 397 }
407 398
408 399 RWCollectable *doJobMsg = (RWCollectable *)dmake_job_msg;
409 400 sigset_t newset;
410 401 sigset_t oldset;
411 402
412 403 AVO_BLOCK_INTERUPTS;
413 404 int xdrResult = xdr(&xdrs_out, doJobMsg);
414 405
415 406 if (xdrResult) {
416 407 fflush(dmake_ofp);
417 408 AVO_UNBLOCK_INTERUPTS;
418 409 } else {
419 410 AVO_UNBLOCK_INTERUPTS;
420 411 fatal(catgets(catd, 1, 249, "Couldn't send the job request to rxm"));
421 412 }
422 413
423 414 delete dmake_job_msg;
424 415 }
425 416
426 417 // Queue for JobResult messages.
427 418 static RWSlistCollectablesQueue jobResultQueue;
428 419
429 420 // Queue for Acknowledge messages.
430 421 static RWSlistCollectablesQueue acknowledgeQueue;
431 422
432 423 // Read a message from the rxm process, and put it into a queue, by
433 424 // message type. Return the message type.
434 425
435 426 int
436 427 getRxmMessage(void)
437 428 {
438 429 RWCollectable *msg = (RWCollectable *)0;
439 430 int msgType = 0;
440 431 // sigset_t newset;
441 432 // sigset_t oldset;
442 433
443 434 // It seems unnecessarily to block interrupts here because
444 435 // any nonignored signal means exit for dmake in distributed mode.
445 436 // AVO_BLOCK_INTERUPTS;
446 437 int xdrResult = xdr(&xdrs_in, msg);
447 438 // AVO_UNBLOCK_INTERUPTS;
448 439
449 440 if (xdrResult) {
450 441 switch(msg->isA()) {
451 442 case __AVO_ACKNOWLEDGEMSG:
452 443 acknowledgeQueue.append(msg);
453 444 msgType = __AVO_ACKNOWLEDGEMSG;
454 445 break;
455 446 case __AVO_JOBRESULTMSG:
456 447 jobResultQueue.append(msg);
457 448 msgType = __AVO_JOBRESULTMSG;
458 449 break;
459 450 default:
460 451 warning(catgets(catd, 1, 291, "Unknown message on rxm input fd"));
461 452 msgType = 0;
462 453 break;
463 454 }
464 455 } else {
465 456 if (errno == EINTR) {
466 457 fputs(NOCATGETS("dmake: Internal error: xdr() has been interrupted by a signal.\n"), stderr);
467 458 }
468 459 fatal(catgets(catd, 1, 250, "Couldn't receive message from rxm"));
469 460 }
470 461
471 462 return msgType;
472 463 }
473 464
474 465 // Get a JobResult message from it's queue, and
475 466 // if the queue is empty, call the getRxmMessage() function until
476 467 // a JobResult message shows.
477 468
478 469 Avo_JobResultMsg *
479 470 getJobResultMsg(void)
480 471 {
481 472 RWCollectable *msg = 0;
482 473
483 474 if (!(msg = jobResultQueue.get())) {
484 475 while (getRxmMessage() != __AVO_JOBRESULTMSG);
485 476 msg = jobResultQueue.get();
486 477 }
487 478
488 479 return (Avo_JobResultMsg *)msg;
489 480 }
490 481
491 482 // Get an Acknowledge message from it's queue, and
492 483 // if the queue is empty, call the getRxmMessage() function until
493 484 // a Acknowledge message shows.
494 485
495 486 Avo_AcknowledgeMsg *
496 487 getAcknowledgeMsg(void)
497 488 {
498 489 RWCollectable *msg = 0;
499 490
500 491 if (!(msg = acknowledgeQueue.get())) {
501 492 while (getRxmMessage() != __AVO_ACKNOWLEDGEMSG);
502 493 msg = acknowledgeQueue.get();
503 494 }
504 495
505 496 return (Avo_AcknowledgeMsg *)msg;
506 497 }
507 498
508 499
509 500 /*
510 501 * Doname
511 502 * await_dist(Boolean waitflg)
512 503 *
513 504 * Waits for distributed children to exit and finishes their processing.
514 505 * Rxm will send a msg down the pipe when a child is done.
515 506 *
516 507 */
517 508 Doname
518 509 await_dist(Boolean waitflg)
519 510 {
520 511 Avo_JobResultMsg *dmake_result_msg;
521 512 int job_msg_id;
522 513 Doname result = build_ok;
523 514 int result_msg_cmd_status;
524 515 int result_msg_job_status;
525 516 Running rp;
526 517
527 518 while (!(dmake_result_msg = getJobResultMsg()));
528 519 job_msg_id = dmake_result_msg->getId();
529 520 result_msg_cmd_status = dmake_result_msg->getCmdStatus();
530 521 result_msg_job_status = dmake_result_msg->getJobStatus();
531 522
532 523 if (waitflg) {
533 524 result = (result_msg_cmd_status == 0) ? build_ok : build_failed;
534 525
535 526 #ifdef PRINT_EXIT_STATUS
536 527 if (result == build_ok) {
537 528 warning(NOCATGETS("I'm in await_dist(), waitflg is true, and result is build_ok."));
538 529 } else {
539 530 warning(NOCATGETS("I'm in await_dist(), waitflg is true, and result is build_failed."));
540 531 }
541 532 #endif
542 533
543 534 } else {
544 535 for (rp = running_list;
545 536 (rp != NULL) && (job_msg_id != rp->job_msg_id);
546 537 rp = rp->next) {
547 538 }
548 539 if (rp == NULL) {
549 540 fatal(catgets(catd, 1, 251, "Internal error: returned child job_msg_id not in running_list"));
550 541 } else {
551 542 /* XXX - This may not be correct! */
552 543 if (result_msg_job_status == RETURNED) {
553 544 rp->state = build_ok;
554 545 } else {
555 546 rp->state = (result_msg_cmd_status == 0) ? build_ok : build_failed;
556 547 }
557 548 result = rp->state;
558 549
559 550 #ifdef PRINT_EXIT_STATUS
560 551 if (result == build_ok) {
561 552 warning(NOCATGETS("I'm in await_dist(), waitflg is false, and result is build_ok."));
562 553 } else {
563 554 warning(NOCATGETS("I'm in await_dist(), waitflg is false, and result is build_failed."));
564 555 }
565 556 #endif
566 557
567 558 }
568 559 parallel_process_cnt--;
569 560 }
570 561 delete dmake_result_msg;
571 562 return result;
572 563 }
573 564
574 565 #endif
575 566
576 567
↓ open down ↓ |
295 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX