| Yoshisato Yanagisawa | 2cb0e5d | 2019-01-10 10:14:16 +0900 | [diff] [blame] | 1 | // Copyright 2018 Google Inc. All rights reserved. | 
|  | 2 | // | 
|  | 3 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 4 | // you may not use this file except in compliance with the License. | 
|  | 5 | // You may obtain a copy of the License at | 
|  | 6 | // | 
|  | 7 | //     http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 8 | // | 
|  | 9 | // Unless required by applicable law or agreed to in writing, software | 
|  | 10 | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 12 | // See the License for the specific language governing permissions and | 
|  | 13 | // limitations under the License. | 
|  | 14 |  | 
|  | 15 | package build | 
|  | 16 |  | 
|  | 17 | import ( | 
| Yoshisato Yanagisawa | 0c517bd | 2019-01-11 12:30:37 +0900 | [diff] [blame] | 18 | "fmt" | 
|  | 19 | "math" | 
| Yoshisato Yanagisawa | 2cb0e5d | 2019-01-10 10:14:16 +0900 | [diff] [blame] | 20 | "path/filepath" | 
| Yoshisato Yanagisawa | 0c517bd | 2019-01-11 12:30:37 +0900 | [diff] [blame] | 21 | "strconv" | 
|  | 22 | "strings" | 
| Yoshisato Yanagisawa | 2cb0e5d | 2019-01-10 10:14:16 +0900 | [diff] [blame] | 23 |  | 
|  | 24 | "android/soong/ui/metrics" | 
|  | 25 | ) | 
|  | 26 |  | 
|  | 27 | const gomaCtlScript = "goma_ctl.py" | 
| Yoshisato Yanagisawa | 0c517bd | 2019-01-11 12:30:37 +0900 | [diff] [blame] | 28 | const gomaLeastNProcs = 2500 | 
|  | 29 | const gomaLeastNFiles = 16000 | 
| Yoshisato Yanagisawa | 2cb0e5d | 2019-01-10 10:14:16 +0900 | [diff] [blame] | 30 |  | 
| Yoshisato Yanagisawa | 0c517bd | 2019-01-11 12:30:37 +0900 | [diff] [blame] | 31 | // ulimit returns ulimit result for |opt|. | 
|  | 32 | // if the resource is unlimited, it returns math.MaxInt32 so that a caller do | 
|  | 33 | // not need special handling of the returned value. | 
|  | 34 | // | 
|  | 35 | // Note that since go syscall package do not have RLIMIT_NPROC constant, | 
|  | 36 | // we use bash ulimit instead. | 
|  | 37 | func ulimitOrFatal(ctx Context, config Config, opt string) int { | 
|  | 38 | commandText := fmt.Sprintf("ulimit %s", opt) | 
|  | 39 | cmd := Command(ctx, config, commandText, "bash", "-c", commandText) | 
|  | 40 | output := strings.TrimRight(string(cmd.CombinedOutputOrFatal()), "\n") | 
|  | 41 | ctx.Verbose(output + "\n") | 
|  | 42 | ctx.Verbose("done\n") | 
| Yoshisato Yanagisawa | 2cb0e5d | 2019-01-10 10:14:16 +0900 | [diff] [blame] | 43 |  | 
| Yoshisato Yanagisawa | 0c517bd | 2019-01-11 12:30:37 +0900 | [diff] [blame] | 44 | if output == "unlimited" { | 
|  | 45 | return math.MaxInt32 | 
|  | 46 | } | 
|  | 47 | num, err := strconv.Atoi(output) | 
|  | 48 | if err != nil { | 
|  | 49 | ctx.Fatalf("ulimit returned unexpected value: %s: %v\n", opt, err) | 
|  | 50 | } | 
|  | 51 | return num | 
|  | 52 | } | 
|  | 53 |  | 
|  | 54 | func startGoma(ctx Context, config Config) { | 
| Yoshisato Yanagisawa | 2cb0e5d | 2019-01-10 10:14:16 +0900 | [diff] [blame] | 55 | ctx.BeginTrace(metrics.RunSetupTool, "goma_ctl") | 
|  | 56 | defer ctx.EndTrace() | 
|  | 57 |  | 
| Yoshisato Yanagisawa | 0c517bd | 2019-01-11 12:30:37 +0900 | [diff] [blame] | 58 | if u := ulimitOrFatal(ctx, config, "-u"); u < gomaLeastNProcs { | 
|  | 59 | ctx.Fatalf("max user processes is insufficient: %d; want >= %d.\n", u, gomaLeastNProcs) | 
|  | 60 | } | 
|  | 61 | if n := ulimitOrFatal(ctx, config, "-n"); n < gomaLeastNFiles { | 
|  | 62 | ctx.Fatalf("max open files is insufficient: %d; want >= %d.\n", n, gomaLeastNFiles) | 
|  | 63 | } | 
|  | 64 |  | 
| Yoshisato Yanagisawa | 2cb0e5d | 2019-01-10 10:14:16 +0900 | [diff] [blame] | 65 | var gomaCtl string | 
|  | 66 | if gomaDir, ok := config.Environment().Get("GOMA_DIR"); ok { | 
|  | 67 | gomaCtl = filepath.Join(gomaDir, gomaCtlScript) | 
|  | 68 | } else if home, ok := config.Environment().Get("HOME"); ok { | 
|  | 69 | gomaCtl = filepath.Join(home, "goma", gomaCtlScript) | 
|  | 70 | } else { | 
| Yoshisato Yanagisawa | 0c517bd | 2019-01-11 12:30:37 +0900 | [diff] [blame] | 71 | ctx.Fatalln("goma_ctl.py not found") | 
| Yoshisato Yanagisawa | 2cb0e5d | 2019-01-10 10:14:16 +0900 | [diff] [blame] | 72 | } | 
|  | 73 |  | 
|  | 74 | cmd := Command(ctx, config, "goma_ctl.py ensure_start", gomaCtl, "ensure_start") | 
|  | 75 |  | 
| Yoshisato Yanagisawa | 02eacca | 2019-02-13 10:47:32 +0900 | [diff] [blame] | 76 | if output, err := cmd.CombinedOutput(); err != nil { | 
|  | 77 | ctx.Fatalf("goma_ctl.py ensure_start failed with: %v\n%s\n", err, output) | 
| Yoshisato Yanagisawa | 2cb0e5d | 2019-01-10 10:14:16 +0900 | [diff] [blame] | 78 | } | 
| Yoshisato Yanagisawa | 2cb0e5d | 2019-01-10 10:14:16 +0900 | [diff] [blame] | 79 | } |