From 0886e530ca97b999275db31870ad8d4924bb3172 Mon Sep 17 00:00:00 2001 From: Yerden Zhumabekov Date: Sun, 27 Oct 2019 00:18:56 +0600 Subject: [PATCH] eal: replace monstrous options You may specify parameters to EAL in a more flexible and direct way with NewParameter function. Please see tests. Signed-off-by: Yerden Zhumabekov --- eal/eal.go | 10 +-- eal/options.go | 219 +++++++------------------------------------------ 2 files changed, 34 insertions(+), 195 deletions(-) diff --git a/eal/eal.go b/eal/eal.go index 6ed5b81..a793ac9 100644 --- a/eal/eal.go +++ b/eal/eal.go @@ -258,11 +258,11 @@ func Init(input string) error { return InitWithArgs(argv) } -// InitWithOpts initializes EAL as in rte_eal_init. Options are -// specified in array of Option-s. These options are then used to -// construct argv array and InitWithArgs is then called upon. -func InitWithOpts(opts ...Option) error { - return InitWithArgs(OptArgs(opts)) +// InitWithParams initializes EAL as in rte_eal_init. Options are +// specified with arrays of parameters which are then joined +// and InitWithArgs is then called upon. +func InitWithParams(p ...Parameter) error { + return InitWithArgs(Join(p)) } // HasHugePages tells if huge pages are activated. diff --git a/eal/options.go b/eal/options.go index 9962f63..f40afe3 100644 --- a/eal/options.go +++ b/eal/options.go @@ -3,207 +3,46 @@ package eal import ( "fmt" "strings" + "unicode" ) -var ( - optAppend = false - optReplace = !optAppend -) - -// single EAL command line option -type cmdOption struct { - option string - value *string -} - -// create either option-value or single option -func newOption(replace bool, tokens ...string) Option { - var x cmdOption - - x.option = tokens[0] - if len(tokens) > 1 { - b := tokens[1] - x.value = &b - } - - return Option{func(p *ealOptions) { p.add(x, replace) }} -} - -// options array for EAL -type ealOptions struct { - opts []cmdOption -} - -func (p *ealOptions) find(option string) *cmdOption { - for i := range p.opts { - if opt := &p.opts[i]; opt.option == option { - return opt - } - } - return nil -} - -// adds new options or replaces the option to EAL if it was already -// given -func (p *ealOptions) add(in cmdOption, replace bool) { - if replace == optReplace { - if opt := p.find(in.option); opt != nil { - *opt = in - return - } - } - p.opts = append(p.opts, in) -} - -func optFlag(key string, replace bool) Option { - return newOption(replace, key) -} - -func optInteger(key string, value interface{}, replace bool) Option { - return newOption(replace, key, fmt.Sprintf("%d", value)) +// Parameter specifies a command line option-argument pair. If +// keyword Opt doesn't imply argument value, Arg should be "". +type Parameter struct { + Opt, Arg string } -func optString(key string, value string, replace bool) Option { - return newOption(replace, key, value) -} - -// convert options array into argv array for rte_eal_init. -func (p *ealOptions) argv() []string { - s := []string{} - for _, opt := range p.opts { - if opt.option == "" { - panic("incorrect options code") - } else if opt.value == nil { - s = append(s, opt.option) - } else if opt.option[:2] == "--" { - s = append(s, opt.option+"="+*opt.value) +// Set mutates Parameter setting new value to option in a form +// array of values. +func (p Parameter) Set(a ...interface{}) Parameter { + if len(a) > 0 { + if arg, ok := a[0].(string); ok { + p.Arg = fmt.Sprintf(arg, a[1:]...) } else { - s = append(s, opt.option) - s = append(s, *opt.value) + p.Arg = fmt.Sprint(a...) } } - return s -} - -func (p *ealOptions) String() string { - return fmt.Sprintln(p.argv()) -} - -// Option represents an option for EAL initialization. Options may be -// combined in array. Some options may be specified several times in a -// row, some may only happen once. -type Option struct { - f func(*ealOptions) -} - -// OptLcores sets mask of the cores to run on. Please note that this -// is a mandatory option. -func OptLcores(mask Set) Option { - return optString("-c", SetToHex(mask, MaxLcore), optReplace) -} - -// OptMasterLcore specifies core ID that is used as master. -func OptMasterLcore(n int) Option { - return optInteger("--master-lcore", n, optReplace) -} - -// OptServiceLcores specifies mask of cores to be used as service -// cores. -func OptServiceLcores(mask Set) Option { - return optString("-s", SetToHex(mask, MaxLcore), optReplace) -} - -// OptBlacklistDev blacklists a PCI device to prevent EAL from using -// it. Multiple option instances are allowed. This option negates -// OptWhitelistDev. -func OptBlacklistDev(dev string) Option { - return optString("--pci-blacklist", dev, optAppend) -} - -// OptWhitelistDev adds a PCI device in white list. Multiple option -// instances are allowed. This option negates OptBlacklistDev. -func OptWhitelistDev(dev string) Option { - return optString("--pci-whitelist", dev, optAppend) -} - -// OptFilePrefix specifies a different shared data file prefix for a -// DPDK process. This option allows running multiple independent DPDK -// primary/secondary processes under different prefixes. -func OptFilePrefix(prefix string) Option { - return optString("--file-prefix", prefix, optReplace) -} - -// OptMemory specifies amount of memory to preallocate at startup. -func OptMemory(n int) Option { - return optInteger("-m", n, optReplace) -} - -// OptBaseVirtAddr attempts to use a different starting address for all -// memory maps of the primary DPDK process. This can be helpful if -// secondary processes cannot start due to conflicts in address map. -func OptBaseVirtAddr(addr uintptr) Option { - return optInteger("--base-virtaddr", addr, optReplace) -} - -// OptLoadExternalPath loads external drivers. An argument can be a -// single shared object file, or a directory containing multiple -// driver shared objects. Multiple option instances are allowed. -func OptLoadExternalPath(path string) Option { - return optString("-d", path, optAppend) -} - -// OptProcType sets the type of the current process. It can either be -// ProcPrimary, ProcSecondary or ProcAuto. -func OptProcType(typ int) Option { - switch typ { - default: - fallthrough - case ProcPrimary: - return optString("--proc-type", "primary", optReplace) - case ProcSecondary: - return optString("--proc-type", "secondary", optReplace) - case ProcAuto: - return optString("--proc-type", "auto", optReplace) - } -} - -// OptMemoryChannels sets the number of memory channels to use. -func OptMemoryChannels(n int) Option { - return optInteger("-n", n, optReplace) + return p } -// OptSocketMemory preallocates specified amounts of memory per -// socket. The number is specified as megabytes with each value for -// a socket. -func OptSocketMemory(mem ...int) Option { - var s []string - for _, m := range mem { - s = append(s, fmt.Sprintf("%d", m)) +// Join creates command line out of parameters. +func Join(params []Parameter) []string { + argv := make([]string, 0, 2*len(params)) + for _, p := range params { + if argv = append(argv, p.Opt); p.Arg != "" { + argv = append(argv, p.Arg) + } } - return optString("--socket-mem", strings.Join(s, ","), optReplace) + return argv } -var ( - // OptNoPCI disables PCI bus. - OptNoPCI = optFlag("--no-pci", optReplace) - - // OptNoHuge uses anonymous memory instead of hugepages (implies - // no secondary process support). - OptNoHuge = optFlag("--no-huge", optReplace) - - // OptInMemory instructs not to create any shared data structures - // and run entirely in memory. Implies --no-shconf and (if - // applicable) --huge-unlink. - OptInMemory = optFlag("--in-memory", optReplace) -) - -// OptArgs parses array of Options and return argv array for -// rte_eal_init() call. -func OptArgs(opts []Option) []string { - p := ealOptions{} - for _, opt := range opts { - opt.f(&p) +// NewParameter creates new Parameter with opt as a keyword and an +// optional array of values which constitute opt's value. +// +// Panic will be emitted if opt contains whitespace. +func NewParameter(opt string, a ...interface{}) Parameter { + if strings.IndexFunc(opt, unicode.IsSpace) < 0 { + return Parameter{Opt: opt}.Set(a...) } - - return p.argv() + panic("invalid option '" + opt + "'") }