cubefs
345 строк · 8.1 Кб
1// Copyright 2018 Tobias Klauser. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package sysconf6
7import (8"bufio"9"io/ioutil"10"os"11"runtime"12"strconv"13"strings"14
15"github.com/tklauser/numcpus"16"golang.org/x/sys/unix"17)
18
19const (20// CLK_TCK is a constant on Linux for all architectures except alpha and ia64.21// See e.g.22// https://git.musl-libc.org/cgit/musl/tree/src/conf/sysconf.c#n3023// https://github.com/containerd/cgroups/pull/1224// https://lore.kernel.org/lkml/agtlq6$iht$1@penguin.transmeta.com/25_SYSTEM_CLK_TCK = 10026)
27
28func readProcFsInt64(path string, fallback int64) int64 {29data, err := ioutil.ReadFile(path)30if err != nil {31return fallback32}33i, err := strconv.ParseInt(string(data[:len(data)-1]), 0, 64)34if err != nil {35return fallback36}37return i38}
39
40// getMemPages computes mem*unit/os.Getpagesize(), but avoids overflowing int64.
41func getMemPages(mem uint64, unit uint32) int64 {42pageSize := os.Getpagesize()43for unit > 1 && pageSize > 1 {44unit >>= 145pageSize >>= 146}47mem *= uint64(unit)48for pageSize > 1 {49pageSize >>= 150mem >>= 151}52return int64(mem)53}
54
55func getPhysPages() int64 {56var si unix.Sysinfo_t57err := unix.Sysinfo(&si)58if err != nil {59return int64(0)60}61return getMemPages(uint64(si.Totalram), si.Unit)62}
63
64func getAvPhysPages() int64 {65var si unix.Sysinfo_t66err := unix.Sysinfo(&si)67if err != nil {68return int64(0)69}70return getMemPages(uint64(si.Freeram), si.Unit)71}
72
73func getNprocsSysfs() (int64, error) {74n, err := numcpus.GetOnline()75return int64(n), err76}
77
78func getNprocsProcStat() (int64, error) {79f, err := os.Open("/proc/stat")80if err != nil {81return -1, err82}83defer f.Close()84
85count := int64(0)86s := bufio.NewScanner(f)87for s.Scan() {88if line := strings.TrimSpace(s.Text()); strings.HasPrefix(line, "cpu") {89l := strings.SplitN(line, " ", 2)90_, err := strconv.ParseInt(l[0][3:], 10, 64)91if err == nil {92count++93}94} else {95// The current format of /proc/stat has all the96// cpu* lines at the beginning. Assume this97// stays this way.98break99}100}101return count, nil102}
103
104func getNprocs() int64 {105count, err := getNprocsSysfs()106if err == nil {107return count108}109
110count, err = getNprocsProcStat()111if err == nil {112return count113}114
115// default to the value determined at runtime startup if all else fails116return int64(runtime.NumCPU())117}
118
119func getNprocsConf() int64 {120count, err := numcpus.GetConfigured()121if err == nil {122return int64(count)123}124
125// TODO(tk): fall back to reading /proc/cpuinfo on legacy systems126// without sysfs?127
128return getNprocs()129}
130
131func hasClock(clockid int32) bool {132var res unix.Timespec133if err := unix.ClockGetres(clockid, &res); err != nil {134return false135}136return true137}
138
139func max(a, b int64) int64 {140if a > b {141return a142}143return b144}
145
146func sysconf(name int) (int64, error) {147switch name {148case SC_AIO_LISTIO_MAX:149return -1, nil150case SC_AIO_MAX:151return -1, nil152case SC_AIO_PRIO_DELTA_MAX:153return _AIO_PRIO_DELTA_MAX, nil154case SC_ARG_MAX:155argMax := int64(_POSIX_ARG_MAX)156var rlim unix.Rlimit157if err := unix.Getrlimit(unix.RLIMIT_STACK, &rlim); err == nil {158argMax = max(argMax, int64(rlim.Cur/4))159}160return argMax, nil161case SC_ATEXIT_MAX:162return _INT_MAX, nil163case SC_CHILD_MAX:164childMax := int64(-1)165var rlim unix.Rlimit166if err := unix.Getrlimit(unix.RLIMIT_NPROC, &rlim); err == nil && rlim.Cur != unix.RLIM_INFINITY {167childMax = int64(rlim.Cur)168}169return childMax, nil170case SC_CLK_TCK:171return _SYSTEM_CLK_TCK, nil172case SC_DELAYTIMER_MAX:173return _DELAYTIMER_MAX, nil174case SC_GETGR_R_SIZE_MAX:175return _NSS_BUFLEN_GROUP, nil176case SC_GETPW_R_SIZE_MAX:177return _NSS_BUFLEN_PASSWD, nil178case SC_MQ_OPEN_MAX:179return -1, nil180case SC_MQ_PRIO_MAX:181return _MQ_PRIO_MAX, nil182case SC_NGROUPS_MAX:183return readProcFsInt64("/proc/sys/kernel/ngroups_max", _NGROUPS_MAX), nil184case SC_OPEN_MAX:185openMax := int64(_OPEN_MAX)186var rlim unix.Rlimit187if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rlim); err == nil {188openMax = int64(rlim.Cur)189}190return openMax, nil191case SC_RTSIG_MAX:192return _RTSIG_MAX, nil193case SC_SEM_NSEMS_MAX:194return -1, nil195case SC_SEM_VALUE_MAX:196return _SEM_VALUE_MAX, nil197case SC_SIGQUEUE_MAX:198var rlim unix.Rlimit199if err := unix.Getrlimit(unix.RLIMIT_SIGPENDING, &rlim); err == nil {200return int64(rlim.Cur), nil201}202return readProcFsInt64("/proc/sys/kernel/rtsig-max", _POSIX_SIGQUEUE_MAX), nil203case SC_STREAM_MAX:204return _STREAM_MAX, nil205case SC_THREAD_DESTRUCTOR_ITERATIONS:206return _POSIX_THREAD_DESTRUCTOR_ITERATIONS, nil207case SC_THREAD_KEYS_MAX:208return _PTHREAD_KEYS_MAX, nil209case SC_THREAD_PRIO_INHERIT:210return _POSIX_THREAD_PRIO_INHERIT, nil211case SC_THREAD_PRIO_PROTECT:212return _POSIX_THREAD_PRIO_PROTECT, nil213case SC_THREAD_STACK_MIN:214return _PTHREAD_STACK_MIN, nil215case SC_THREAD_THREADS_MAX:216return -1, nil217case SC_TIMER_MAX:218return -1, nil219case SC_TTY_NAME_MAX:220return _TTY_NAME_MAX, nil221case SC_TZNAME_MAX:222return -1, nil223
224case SC_CPUTIME:225if hasClock(unix.CLOCK_PROCESS_CPUTIME_ID) {226return _POSIX_VERSION, nil227}228return -1, nil229case SC_MONOTONIC_CLOCK:230if hasClock(unix.CLOCK_MONOTONIC) {231return _POSIX_VERSION, nil232}233return -1, nil234case SC_SAVED_IDS:235return _POSIX_SAVED_IDS, nil236case SC_SPAWN:237return _POSIX_SPAWN, nil238case SC_SPIN_LOCKS:239return _POSIX_SPIN_LOCKS, nil240case SC_SPORADIC_SERVER:241return _POSIX_SPORADIC_SERVER, nil242case SC_SYNCHRONIZED_IO:243return _POSIX_SYNCHRONIZED_IO, nil244case SC_THREAD_ATTR_STACKADDR:245return _POSIX_THREAD_ATTR_STACKADDR, nil246case SC_THREAD_ATTR_STACKSIZE:247return _POSIX_THREAD_ATTR_STACKSIZE, nil248case SC_THREAD_CPUTIME:249if hasClock(unix.CLOCK_THREAD_CPUTIME_ID) {250return _POSIX_VERSION, nil251}252return -1, nil253case SC_THREAD_PRIORITY_SCHEDULING:254return _POSIX_THREAD_PRIORITY_SCHEDULING, nil255case SC_THREAD_PROCESS_SHARED:256return _POSIX_THREAD_PROCESS_SHARED, nil257case SC_THREAD_SAFE_FUNCTIONS:258return _POSIX_THREAD_SAFE_FUNCTIONS, nil259case SC_THREAD_SPORADIC_SERVER:260return _POSIX_THREAD_SPORADIC_SERVER, nil261case SC_TRACE:262return _POSIX_TRACE, nil263case SC_TRACE_EVENT_FILTER:264return _POSIX_TRACE_EVENT_FILTER, nil265case SC_TRACE_EVENT_NAME_MAX:266return -1, nil267case SC_TRACE_INHERIT:268return _POSIX_TRACE_INHERIT, nil269case SC_TRACE_LOG:270return _POSIX_TRACE_LOG, nil271case SC_TRACE_NAME_MAX:272return -1, nil273case SC_TRACE_SYS_MAX:274return -1, nil275case SC_TRACE_USER_EVENT_MAX:276return -1, nil277case SC_TYPED_MEMORY_OBJECTS:278return _POSIX_TYPED_MEMORY_OBJECTS, nil279
280case SC_V7_ILP32_OFF32:281return _POSIX_V7_ILP32_OFF32, nil282case SC_V7_ILP32_OFFBIG:283return _POSIX_V7_ILP32_OFFBIG, nil284case SC_V7_LP64_OFF64:285return _POSIX_V7_LP64_OFF64, nil286case SC_V7_LPBIG_OFFBIG:287return _POSIX_V7_LPBIG_OFFBIG, nil288
289case SC_V6_ILP32_OFF32:290return _POSIX_V6_ILP32_OFF32, nil291case SC_V6_ILP32_OFFBIG:292return _POSIX_V6_ILP32_OFFBIG, nil293case SC_V6_LP64_OFF64:294return _POSIX_V6_LP64_OFF64, nil295case SC_V6_LPBIG_OFFBIG:296return _POSIX_V6_LPBIG_OFFBIG, nil297
298case SC_2_C_VERSION:299return _POSIX2_C_VERSION, nil300case SC_2_CHAR_TERM:301return _POSIX2_CHAR_TERM, nil302case SC_2_PBS,303SC_2_PBS_ACCOUNTING,304SC_2_PBS_CHECKPOINT,305SC_2_PBS_LOCATE,306SC_2_PBS_MESSAGE,307SC_2_PBS_TRACK:308return -1, nil309case SC_2_UPE:310return -1, nil311
312case SC_XOPEN_CRYPT:313// removed in glibc 2.28314return -1, nil315case SC_XOPEN_ENH_I18N:316return _XOPEN_ENH_I18N, nil317case SC_XOPEN_REALTIME:318return _XOPEN_REALTIME, nil319case SC_XOPEN_REALTIME_THREADS:320return _XOPEN_REALTIME_THREADS, nil321case SC_XOPEN_SHM:322return _XOPEN_SHM, nil323case SC_XOPEN_STREAMS:324return -1, nil325case SC_XOPEN_UNIX:326return _XOPEN_UNIX, nil327case SC_XOPEN_VERSION:328return _XOPEN_VERSION, nil329case SC_XOPEN_XCU_VERSION:330return _XOPEN_XCU_VERSION, nil331
332case SC_PHYS_PAGES:333return getPhysPages(), nil334case SC_AVPHYS_PAGES:335return getAvPhysPages(), nil336case SC_NPROCESSORS_CONF:337return getNprocsConf(), nil338case SC_NPROCESSORS_ONLN:339return getNprocs(), nil340case SC_UIO_MAXIOV: // same as _SC_IOV_MAX341return _UIO_MAXIOV, nil342}343
344return sysconfGeneric(name)345}
346