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