From c3d9b392ddc771673bb1ede7b61dfb4205ebbbf2 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Wed, 17 Apr 2019 15:50:38 +0200 Subject: [PATCH] Scaling large lists report --- CHANGELOG.md | 1 + README.md | 3 +- doc/large-lists.md | 134 ------------- doc/scaling/clixon-commit-0.png | Bin 0 -> 6810 bytes doc/scaling/clixon-delete-100.png | Bin 0 -> 8666 bytes doc/scaling/clixon-get-0.png | Bin 0 -> 8200 bytes doc/scaling/clixon-get-100.png | Bin 0 -> 8588 bytes doc/scaling/clixon-put-0.png | Bin 0 -> 7917 bytes doc/scaling/clixon-put-100.png | Bin 0 -> 8277 bytes doc/scaling/large-lists.md | 131 +++++++++++++ example/README.md | 3 +- test/plot_perf.sh | 312 +++++++++++++++++++++--------- 12 files changed, 354 insertions(+), 230 deletions(-) delete mode 100644 doc/large-lists.md create mode 100644 doc/scaling/clixon-commit-0.png create mode 100644 doc/scaling/clixon-delete-100.png create mode 100644 doc/scaling/clixon-get-0.png create mode 100644 doc/scaling/clixon-get-100.png create mode 100644 doc/scaling/clixon-put-0.png create mode 100644 doc/scaling/clixon-put-100.png create mode 100644 doc/scaling/large-lists.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 7edfe80e..57215d1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -102,6 +102,7 @@ ### Minor changes +* A scaling of [large lists](doc/scaling) report is added * A new "hello world" example is added * Optimized validation of large lists * New xmldb_get1() returning actual cache - not a copy. This has lead to some householding instead of just deleting the copy diff --git a/README.md b/README.md index 38385af8..b26a32d2 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ support. * [Background](#background) * [Frequently asked questions (FAQ)](doc/FAQ.md) + * [Hello world](example/hello/README.md) * [Changelog](CHANGELOG.md) * [Installation](#installation) * [Licenses](#licenses) @@ -26,7 +27,7 @@ support. * [Runtime](#runtime) * [Clixon project page](http://www.clicon.org) * [Tests and CI](test/README.md) - * [Scaling: large lists](doc/large-lists.md) + * [Scaling: large lists](doc/scaling/large-lists.md) * [Containers](docker/README.md) * [Roadmap](doc/ROADMAP.md) * [Reference manual](#reference) diff --git a/doc/large-lists.md b/doc/large-lists.md deleted file mode 100644 index 1b1b15a4..00000000 --- a/doc/large-lists.md +++ /dev/null @@ -1,134 +0,0 @@ -# Large lists in Clixon - - * [Background](#background) - * [Overview](#overview) - * [Test descriptions]#test-descriptions) - -## Background - -Clixon is a configuration management tool. In this paper the case of -a large number of "flat" list and leaf-list entries are investigated. -There may be other scaling usecases, such as large configuratin -"depth", large number of requesting clients, etc. However, these are -not investigated here. - -## Overview -The basic case is a large list, according to the following Yang specification: -``` - list y { - key "a"; - leaf a { - type int32; - } - leaf b { - type string; - } - } -``` -where `a` is a unique key and `b` is a payload, useful in replace operations. - -There is also a leaf-list as follows: -``` - leaf-list c { - type string; - } -``` - -XML lists with `N` elements are generated based on -this configuration, eg for `N=10`: -``` - 00 - 11 - 22 - 33 - 44 - 55 - 66 - 77 - 88 - 99 -``` - -Requests are made using a random function, a request on the list above will on the form: -``` - curl -G http://localhost/restconf/data/y=(rnd%$N) -``` - -## Test descriptions - -### Limitations - -Test were not made using CLI interaction. - -### Setup - -The setup consisted of the following components running on the same machine: -* A clixon backend daemon -* A clixon restconf daemon -* An nginx daemon daemon -* A netconf client program -* curl client -* A bash terminal and test script [plot_perf.sh](../test/plot_perf.sh) -* Gnuplot for generating plots - -### Config file -The following Clixon config file was used: -``` - - $cfg - $dir - /usr/local/share/clixon - scaling - /usr/local/var/example/example.sock - /usr/local/var/example/example.pidfile - false - $dir - false - -``` -where `$dir` and `$cfg`are local files. For more info see [plot_perf.sh]. - -### Testcases - -All tests measure the "real" time of a command on a lightly loaded -machine using the Linux command `time(1)`. - -The following tests were made (for each architecture and protocol): -* Write `N` entries in one single operation. (With an empty datastore) -* Read `N` entries in one single operation. (With a datastore of `N` entries) -* Commit `N` entries (With a candidate of `N` entries and empty running) -* Read 1 entry (In a datastore of `N` entries) -* Write/Replace 1 entry (In a datastore of `N` entries) -* Delete 1 entry (In a datastore of `N` entries) - -### Protocols - -The tests are made using: -* Netconf[RFC6241] and -* Restconf[RFC8040]. -Notably, CLI tests are for future study. - -### Architectures - -The tests were made on the following hardware, all running Ubuntu Linux: -* [i686] dual Intel Core Duo processor (IBM Thinkpad X60), 3GB memory -* arm 32-bit (Raspberry PI 3) -* x86 64-bit (Intel NUC) - -### Operating systems - -On i686: -``` -Linux version 4.4.0-143-generic (buildd@lgw01-amd64-037) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10) ) #169-Ubuntu SMP Thu Feb 7 07:56:51 UTC 2019 -``` - -## Results - -## References - -[RFC6241](https://tools.ietf.org/html/rfc6241) "Network Configuration Protocol (NETCONF)" -[RFC8040](https://tools.ietf.org/html/rfc8040) "RESTCONF Protocol" -[i686](https://ark.intel.com/content/www/us/en/ark/products/27235/intel-core-duo-processor-t2400-2m-cache-1-83-ghz-667-mhz-fsb.html) -[plot_perf.sh](../test/plot_perf.sh) Test script - - diff --git a/doc/scaling/clixon-commit-0.png b/doc/scaling/clixon-commit-0.png new file mode 100644 index 0000000000000000000000000000000000000000..cbab820a53fa9f5c76cf72566c34fc37744e724a GIT binary patch literal 6810 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 AtpET3 literal 0 HcmV?d00001 diff --git a/doc/scaling/clixon-delete-100.png b/doc/scaling/clixon-delete-100.png new file mode 100644 index 0000000000000000000000000000000000000000..9396c4831134584b701c0bf69f9e4f34ffc0ad0a GIT binary patch literal 8666 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 D#-31? literal 0 HcmV?d00001 diff --git a/doc/scaling/clixon-get-100.png b/doc/scaling/clixon-get-100.png new file mode 100644 index 0000000000000000000000000000000000000000..246768d4551267e7c77d797b04ee696835520cfe GIT binary patch literal 8588 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 literal 0 HcmV?d00001 diff --git a/doc/scaling/clixon-put-0.png b/doc/scaling/clixon-put-0.png new file mode 100644 index 0000000000000000000000000000000000000000..2e9acc152748845a538a3a750a1c58b6934cc911 GIT binary patch literal 7917 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 V!iUz{6})mF2~Sr)mvv4FO#r~Rw1ofw literal 0 HcmV?d00001 diff --git a/doc/scaling/large-lists.md b/doc/scaling/large-lists.md new file mode 100644 index 00000000..b36f9f2c --- /dev/null +++ b/doc/scaling/large-lists.md @@ -0,0 +1,131 @@ +# Large lists in Clixon + + * [Background](#background) + * [Overview](#overview) + * [Test descriptions](#test-descriptions) + * [Results](#results) + * [References](#references) + +## Background + +CIixon can handle large configurations. Here, large number of elements +in a "flat" list is presented. There are other scaling usecases, +such as large configuratin "depth", large number of requesting +clients, etc. + +## Overview + +The basic case is a large list, according to the following Yang specification: +``` + container x { + description "top-level container"; + list y { + description "List with potential large number of elements"; + key "a"; + leaf a { + description "key in list"; + type int32; + } + leaf b { + description "payload data"; + type string; + } + } + } +``` +where `a` is a unique key and `b` is a payload, useful in replace operations. + +XML lists with `N` elements are generated based on +this configuration, eg for `N=10`: +``` + 00 + 11 + 22 + 33 + 44 + 55 + 66 + 77 + 88 + 99 +``` + +Requests are either made over the _whole_ dataset, or for one specific element. The following example shows a Restconf GET operation of a single element: +``` + curl -X GET http://localhost/restconf/data/scaling:x/y=3 + {"scaling:y": [{"a": 3,"b": "3"}]} + +``` + +Operations of single elements (transactions) are made in a burst of +random elements, typically 100. + +## Tests + +All details of the setup are in the [test script](../../test/plot_perf.sh). + +### Testcases + +All tests measure the "real" time of a command on a lightly loaded +machine using the Linux command `time(1)`. + +The following tests were made (for each architecture and protocol): +* Write `N` entries in one single operation. (With an empty datastore) +* Read `N` entries in one single operation. (With a datastore of `N` entries) +* Commit `N` entries (With a candidate of `N` entries and empty running) +* Read 1 entry (In a datastore of `N` entries) +* Write/Replace 1 entry (In a datastore of `N` entries) +* Delete 1 entry (In a datastore of `N` entries) + +The tests are made using Netconf and Restconf, except commit which is made only for Netconf. + +### Architecture and OS + +The tests were made on the following hardware, all running Ubuntu Linux: +* i686: dual Intel Core Duo processor (IBM Thinkpad X60) +* arm: ARMv7 Processor rev 5 (v7l) (Raspberry PI 2 Model B) +* x86-64: Intel Quad-core I5-8259U (Intel NUC Coffee Lake) + +i686: Ubuntu 16.04.6 LTS +``` +Linux version 4.4.0-143-generic (buildd@lgw01-amd64-037) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10) ) #169-Ubuntu SMP Thu Feb 7 07:56:51 UTC 2019 +``` + +Arm : Raspbian GNU/Linux 9 +``` + +Linux version 4.14.79-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1159 SMP Sun Nov 4 17:50:20 GMT 2018 +``` + +x86_64: Ubuntu 18.04.1 LTS +``` +inux version 4.15.0-47-generic (buildd@lgw01-amd64-001) (gcc version 7.3.0 (Ubuntu 7.3.0-16ubuntu3)) #50-Ubuntu SMP Wed Mar 13 10:44:52 UTC 2019 +``` + +## Results + +![Get config](clixon-get-0.png "Get config") + +![Put config](clixon-put-0.png "Put config") + +![Commit config](clixon-commit-0.png "Commit config") + +![Get single entry](clixon-get-100.png "Get single entry") + +![Put single entry](clixon-put-100.png "Put single entry") + +![Delete single entry](clixon-delete-100.png "Delete single entry") + +## Discussion + + + + +## References + +[RFC6241](https://tools.ietf.org/html/rfc6241) "Network Configuration Protocol (NETCONF)" +[RFC8040](https://tools.ietf.org/html/rfc8040) "RESTCONF Protocol" +[i686](https://ark.intel.com/content/www/us/en/ark/products/27235/intel-core-duo-processor-t2400-2m-cache-1-83-ghz-667-mhz-fsb.html) +[plot_perf.sh](../test/plot_perf.sh) Test script + + diff --git a/example/README.md b/example/README.md index 58cdc401..66149d8b 100644 --- a/example/README.md +++ b/example/README.md @@ -1,6 +1,5 @@ # Clixon examples Clixon have the following examples: - * [Main example](main/README.md) * [Hello world](hello/README.md) - \ No newline at end of file + * [Main example](main/README.md) diff --git a/test/plot_perf.sh b/test/plot_perf.sh index 5cbc3cc7..e4a95acf 100755 --- a/test/plot_perf.sh +++ b/test/plot_perf.sh @@ -1,39 +1,34 @@ #!/bin/bash -# Transactions per second for large lists read/write plotter using gnuplot -# What do I want to plot? -# First: on i32, i64, arm32 -# PART 1: Basic load -# 1. How long to write 100K entries? -# - netconf / restconf -# - list / leaf-list -# 2. How long to read 100K entries? -# - netconf/ restconf -# - list / leaf-list -# 3. How long to commit 100K entries? (netconf) -# - list / leaf-list -# -# PART 2: Load 100K entries. Commit. -# 4. How many read operations per second? -# - netconf/ restconf -# - list / leaf-list -# 5. How many write operations per second? -# - netconf / restconf -# - list / leaf-list -# 6. How may delete operations per second? -# - netconf / restconf -# - list / leaf-list -# The script uses bash builtin "time" command which is somewhat difficult to -# understand. See: https://linux.die.net/man/1/bash # pipelines -# You essentially have to do: { time stuff; } 2>&1 -# See: https://stackoverflow.com/questions/26784870/parsing-the-output-of-bashs-time-builtin +# Performance of large lists. See large-lists.md +# The parameters are shown below (under Default values) +# Examples +# 1. run all measurements up to 10000 entris collect all results in /tmp/plots +# run=true plot=false to=10000 resdir=/tmp/plots ./plot_perf.sh +# 2. Use existing data plot and show on X11 +# run=false plot=true resdir=/tmp/plots term=x11 ./plot_perf.sh +# 3. Use existing data plot i686 and armv7l data as png +# archs="i686 armv7l" run=false plot=true resdir=/tmp/plots term=png ./plot_perf.sh # Magic line must be first in script (see README.md) s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi -# op from step to reqs -to=1000 -step=100 -reqs=100 +arch=$(arch) +# Default values +: ${to:=5000} # Max N +: ${step=1000} # Iterate in steps (also starting point) +: ${reqs=100} # Number of requests in each burst +: ${run:=true} # run tests (or skip them). If false just plot +: ${term:=x11} # x11 interactive, alt: png +: ${resdir=$dir} # Result dir (both data and gnuplot) +: ${plot=false} # Result dir (both data and gnuplot) +: ${archs=$arch} # Plotting can be made for many architectures (not run) + +# 0 prefix to protect against shell dynamic binding) +to0=$to +step0=$step +reqs0=$reqs + +ext=$term # gnuplot output file extenstion # Global variables APPNAME=example @@ -42,6 +37,13 @@ fyang=$dir/plot.yang fxml=$dir/data.xml fjson=$dir/data.json +# Resultdir - if different from $dir that gets erased +#resdir=$dir + +if [ ! -d $resdir ]; then + mkdir $resdir +fi + # For memcheck # clixon_netconf="valgrind --leak-check=full --show-leak-kinds=all clixon_netconf" # clixon_netconf="valgrind --tool=callgrind clixon_netconf @@ -53,19 +55,20 @@ module scaling{ namespace "urn:example:clixon"; prefix sc; container x { - list y { - key "a"; - leaf a { - type uint32; + description "top-level container"; + list y { + description "List with potential large number of elements"; + key "a"; + leaf a { + description "key in list"; + type int32; + } + leaf b { + description "payload data"; + type string; + } } - leaf b { - type string; - } - } - leaf-list c { - type string; - } - } + } } EOF @@ -109,48 +112,49 @@ genfile(){ # where proto is one of: # netconf, restconf # where op is one of: -# writeall readall commitall read write +# get put delete commit runnet(){ op=$1 - n=$2 # Number of entries in DB + nr=$2 # Number of entries in DB (keep diff from n due to shell dynamic binding) reqs=$3 - echo -n "$n " >> $dir/$op-netconf-$reqs + file=$resdir/$op-netconf-$reqs-$arch + echo -n "$nr " >> $file case $op in - write) + put) if [ $reqs = 0 ]; then # Write all in one go - genfile $n netconf; - { time -p cat $fxml | $clixon_netconf -qf $cfg -y $fyang ; } 2>&1 | awk '/real/ {print $2}' >> $dir/$op-netconf-$reqs + genfile $nr netconf; + { time -p cat $fxml | $clixon_netconf -qf $cfg -y $fyang ; } 2>&1 | awk '/real/ {print $2}' | tr , . >> $file else # reqs != 0 { time -p for (( i=0; i<$reqs; i++ )); do - rnd=$(( ( RANDOM % $n ) )); + rnd=$(( ( RANDOM % $nr ) )); echo "$rnd$rnd]]>]]>"; - done | $clixon_netconf -qf $cfg -y $fyang ; } 2>&1 | awk '/real/ {print $2}' >> $dir/$op-netconf-$reqs + done | $clixon_netconf -qf $cfg -y $fyang > /dev/null; } 2>&1 | awk '/real/ {print $2}' | tr , . >> $file fi ;; - read) + get) if [ $reqs = 0 ]; then # Read all in one go - { time -p echo "]]>]]>" | $clixon_netconf -qf $cfg -y $fyang > /dev/null ; } 2>&1 | awk '/real/ {print $2}' >> $dir/$op-netconf-$reqs + { time -p echo "]]>]]>" | $clixon_netconf -qf $cfg -y $fyang > /dev/null ; } 2>&1 | awk '/real/ {print $2}' | tr , . >> $file else # reqs != 0 { time -p for (( i=0; i<$reqs; i++ )); do rnd=$(( ( RANDOM % $nr ) )) - echo "$rnd$rnd]]>]]>" -done | $clixon_netconf -qf $cfg -y $fyang; } 2>&1 | awk '/real/ {print $2}' >> $dir/$op-netconf-$reqs + echo "$rnd$rnd]]>]]>" + done | $clixon_netconf -qf $cfg -y $fyang > /dev/null; } 2>&1 | awk '/real/ {print $2}' | tr , . >> $file fi ;; delete) { time -p for (( i=0; i<$reqs; i++ )); do rnd=$(( ( RANDOM % $nr ) )) - echo "$rnd$rnd]]>]]>" -done | $clixon_netconf -qf $cfg -y $fyang; } 2>&1 | awk '/real/ {print $2}' >> $dir/$op-netconf-$reqs + echo "$rnd$rnd]]>]]>" +done | $clixon_netconf -qf $cfg -y $fyang; } 2>&1 | awk '/real/ {print $2}' | tr , . >> $file ;; commit) - { time -p echo "]]>]]>" | $clixon_netconf -qf $cfg -y $fyang > /dev/null ; } 2>&1 | awk '/real/ {print $2}' >> $dir/$op-netconf-$reqs + { time -p echo "]]>]]>" | $clixon_netconf -qf $cfg -y $fyang > /dev/null ; } 2>&1 | awk '/real/ {print $2}' | tr , . >> $file ;; *) err "Operation not supported" "$op" exit - ;; + ;; esac } @@ -159,43 +163,43 @@ done | $clixon_netconf -qf $cfg -y $fyang; } 2>&1 | awk '/real/ {print $2}' >> $ # where proto is one of: # netconf, restconf # where op is one of: -# writeall readall commitall read write +# get put delete runrest(){ op=$1 - n=$2 # Number of entries in DB + nr=$2 # Number of entries in DB reqs=$3 - echo -n "$n " >> $dir/$op-restconf-$reqs + file=$resdir/$op-restconf-$reqs-$arch + echo -n "$nr " >> $file case $op in - write) + put) if [ $reqs = 0 ]; then # Write all in one go - genfile $n restconf + genfile $nr restconf # restconf @- means from stdin - { time -p curl -sS -X PUT -d @$fjson http://localhost/restconf/data/scaling:x ; } 2>&1 | awk '/real/ {print $2}' >> $dir/$op-restconf-$reqs + { time -p curl -sS -X PUT -d @$fjson http://localhost/restconf/data/scaling:x ; } 2>&1 | awk '/real/ {print $2}' | tr , . >> $file else # Small requests { time -p for (( i=0; i<$reqs; i++ )); do - rnd=$(( ( RANDOM % $n ) )); + rnd=$(( ( RANDOM % $nr ) )); curl -sS -X PUT http://localhost/restconf/data/scaling:x/y=$rnd -d "{\"scaling:y\":{\"a\":$rnd,\"b\":\"$rnd\"}}" - done ; } 2>&1 | awk '/real/ {print $2}' >> $dir/$op-restconf-$reqs + done ; } 2>&1 | awk '/real/ {print $2}' | tr , .>> $file # fi ;; - read) + get) if [ $reqs = 0 ]; then # Read all in one go - { time -p curl -sS -X GET http://localhost/restconf/data/scaling:x > /dev/null; } 2>&1 | awk '/real/ {print $2}' >> $dir/$op-restconf-$reqs + { time -p curl -sS -X GET http://localhost/restconf/data/scaling:x > /dev/null; } 2>&1 | awk '/real/ {print $2}' | tr , . >> $file else # Small requests { time -p for (( i=0; i<$reqs; i++ )); do - rnd=$(( ( RANDOM % $n ) )); + rnd=$(( ( RANDOM % $nr ) )); curl -sS -X GET http://localhost/restconf/data/scaling:x/y=$rnd - done ; } 2>&1 | awk '/real/ {print $2}' >> $dir/$op-restconf-$reqs + done ; } 2>&1 | awk '/real/ {print $2}' | tr , .>> $file fi ;; - delete) + delete) { time -p for (( i=0; i<$reqs; i++ )); do - rnd=$(( ( RANDOM % $n ) )); + rnd=$(( ( RANDOM % $nr ) )); curl -sS -X GET http://localhost/restconf/data/scaling:x/y=$rnd - done ; } 2>&1 | awk '/real/ {print $2}' >> $dir/$op-restconf-$reqs - + done ; } 2>&1 | awk '/real/ {print $2}' | tr , .>> $file ;; *) err "Operation not supported" "$op" @@ -246,8 +250,8 @@ plot(){ fi # reset file - new "Create file $dir/$op-$proto-$reqs" - echo "" > $dir/$op-$proto-$reqs + new "Create file $resdir/$op-$proto-$reqs-$arch" + echo -n "" > $resdir/$op-$proto-$reqs-$arch for (( n=$from; n<=$to; n=$n+$step )); do reset if [ $can = n ]; then @@ -256,7 +260,7 @@ plot(){ commit fi fi - new "$op-$proto-$reqs $n" + new "$op-$proto-$reqs-$arch $n" if [ $proto = netconf ]; then runnet $op $n $reqs else @@ -266,6 +270,7 @@ plot(){ echo # newline } +if $run; then new "test params: -f $cfg -y $fyang" if [ $BE -ne 0 ]; then new "kill old backend" @@ -286,26 +291,35 @@ start_restconf -f $cfg -y $fyang new "waiting" sleep $RCWAIT + +to=$to0 +step=$step0 +reqs=$reqs0 + +# Put all tests for proto in netconf restconf; do - new "$proto write all entries to candidate (restconf:running)" - plot write $proto $step $step $to 0 0 0 # all candidate 0 running 0 + new "$proto put all entries to candidate (restconf:running)" + plot put $proto $step $step $to 0 0 0 # all candidate 0 running 0 done +# Get all tests for proto in netconf restconf; do - new "$proto read all entries from running" - plot read netconf $step $step $to 0 n n # start w full datastore + new "$proto get all entries from running" + plot get $proto $step $step $to 0 n n # start w full datastore done +# Netconf commit all new "Netconf commit all entries from candidate to running" plot commit netconf $step $step $to 0 n 0 # candidate full running empty -reqs=100 +# Transactions get/put/delete +reqs=$reqs0 for proto in netconf restconf; do - new "$proto read $reqs from full database" - plot read $proto $step $step $to $reqs n n + new "$proto get $reqs from full database" + plot get $proto $step $step $to $reqs n n - new "$proto Write $reqs to full database(replace / alter values)" - plot write $proto $step $step $to $reqs n n + new "$proto put $reqs to full database(replace / alter values)" + plot put $proto $step $step $to $reqs n n new "$proto delete $reqs from full database(replace / alter values)" plot delete $proto $step $step $to $reqs n n @@ -324,15 +338,127 @@ if [ $BE -ne 0 ]; then # kill backend stop_backend -f $cfg fi +fi # if run + +if $plot; then + +# 1. Get config +gplot="" +for a in $archs; do + gplot="$gplot \"$resdir/get-restconf-0-$a\" title \"rc-$a\", \"$resdir/get-netconf-0-$a\" title \"nc-$a\"," +done -arch=$(arch) gnuplot -persist <