Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ycai
simbricks
Commits
a5a1ff28
Commit
a5a1ff28
authored
Aug 26, 2024
by
Antoine Kaufmann
Browse files
tweak system spec a bit more with full system image
parent
b34ddb29
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
199 additions
and
29 deletions
+199
-29
experiments/simbricks/orchestration/system/base.py
experiments/simbricks/orchestration/system/base.py
+1
-0
experiments/simbricks/orchestration/system/host/app.py
experiments/simbricks/orchestration/system/host/app.py
+59
-4
experiments/simbricks/orchestration/system/host/base.py
experiments/simbricks/orchestration/system/host/base.py
+108
-18
experiments/simbricks/orchestration/system/host/disk_images.py
...iments/simbricks/orchestration/system/host/disk_images.py
+30
-6
sims/external/gem5
sims/external/gem5
+1
-1
No files found.
experiments/simbricks/orchestration/system/base.py
View file @
a5a1ff28
...
...
@@ -36,6 +36,7 @@ class System:
class
Component
(
abc
.
ABC
):
def
__init__
(
self
,
s
:
System
)
->
None
:
s
.
system
=
s
s
.
parameters
=
{}
s
.
add_component
(
self
)
@
abc
.
abstractmethod
...
...
experiments/simbricks/orchestration/system/host/app.py
View file @
a5a1ff28
...
...
@@ -34,17 +34,24 @@ class Application(abc.ABC):
# Note AK: Maybe we can factor most of the duplicate calls with the host out
# into a separate module.
class
LinuxApplication
(
abc
.
ABC
):
class
Base
LinuxApplication
(
abc
.
ABC
):
def
__init__
(
self
,
h
:
base
.
LinuxHost
)
->
None
:
self
.
host
=
h
self
.
start_delay
:
float
|
None
=
None
self
.
end_delay
:
float
|
None
=
None
self
.
wait
=
True
@
abc
.
abstractmethod
def
run_cmds
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
"""Commands to run on node."""
return
self
.
app
.
run_cmds
(
self
)
pass
def
cleanup_cmds
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
"""Commands to run to cleanup node."""
return
[]
if
self
.
end_delay
is
None
:
return
[]
else
:
return
[
f
'sleep
{
self
.
start_delay
}
'
]
def
config_files
(
self
,
env
:
expenv
.
ExpEnv
)
->
dict
[
str
,
tp
.
IO
]:
"""
...
...
@@ -68,7 +75,10 @@ class LinuxApplication(abc.ABC):
def
prepare_post_cp
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
"""Commands to run to prepare node after checkpoint restore."""
return
[]
if
self
.
end_delay
is
None
:
return
[]
else
:
return
[
f
'sleep
{
self
.
end_delay
}
'
]
def
strfile
(
self
,
s
:
str
)
->
io
.
BytesIO
:
"""
...
...
@@ -79,3 +89,48 @@ class LinuxApplication(abc.ABC):
simulated node.
"""
return
io
.
BytesIO
(
bytes
(
s
,
encoding
=
"UTF-8"
))
class
PingClient
(
BaseLinuxApplication
):
def
__init__
(
self
,
server_ip
:
str
=
'192.168.64.1'
)
->
None
:
super
().
__init__
()
self
.
server_ip
=
server_ip
def
run_cmds
(
self
,
env
:
expenv
.
ExpEnv
)
->
tp
.
List
[
str
]:
return
[
f
'ping
{
self
.
server_ip
}
-c 10'
]
class
Sleep
(
BaseLinuxApplication
):
def
__init__
(
self
,
delay
:
float
=
10
)
->
None
:
super
().
__init__
()
self
.
delay
=
delay
def
run_cmds
(
self
,
env
:
expenv
.
ExpEnv
)
->
tp
.
List
[
str
]:
return
[
f
'sleep
{
self
.
delay
}
'
]
class
NetperfServer
(
BaseLinuxApplication
):
def
__init__
(
self
)
->
None
:
super
().
__init__
()
def
run_cmds
(
self
,
env
:
expenv
.
ExpEnv
)
->
tp
.
List
[
str
]:
return
[
'netserver'
,
'sleep infinity'
]
class
NetperfClient
(
BaseLinuxApplication
):
def
__init__
(
self
,
server_ip
:
str
=
'192.168.64.1'
)
->
None
:
super
().
__init__
()
self
.
server_ip
=
server_ip
self
.
duration_tp
=
10
self
.
duration_lat
=
10
def
run_cmds
(
self
,
env
:
expenv
.
ExpEnv
)
->
tp
.
List
[
str
]:
return
[
'netserver'
,
'sleep 0.5'
,
f
'netperf -H
{
self
.
server_ip
}
-l
{
self
.
duration_tp
}
'
,
(
f
'netperf -H
{
self
.
server_ip
}
-l
{
self
.
duration_lat
}
-t TCP_RR'
' -- -o mean_latency,p50_latency,p90_latency,p99_latency'
)
]
\ No newline at end of file
experiments/simbricks/orchestration/system/host/base.py
View file @
a5a1ff28
...
...
@@ -23,6 +23,7 @@
import
typing
as
tp
import
io
from
os
import
path
from
simbricks.orchestration.experiment
import
experiment_environment
as
expenv
from
simbricks.orchestration.system
import
base
from
simbricks.orchestration.system
import
eth
from
simbricks.orchestration.system
import
mem
...
...
@@ -34,8 +35,8 @@ from simbricks.orchestration.system.host import app
class
Host
(
base
.
Component
):
def
__init__
(
self
,
s
:
base
.
System
):
super
().
__init__
(
s
)
self
.
ifs
:
list
[
pcie
.
PCIeHost
Interface
]
=
[]
self
.
applications
:
list
[
Application
]
self
.
ifs
:
list
[
base
.
Interface
]
=
[]
self
.
applications
:
list
[
app
.
Application
]
def
interfaces
(
self
)
->
list
[
base
.
Interface
]:
return
self
.
pcie_ifs
+
self
.
eth_ifs
+
self
.
mem_ifs
...
...
@@ -43,7 +44,7 @@ class Host(base.Component):
def
add_if
(
self
,
i
:
base
.
Interface
)
->
None
:
self
.
ifs
.
append
(
i
)
def
add_app
(
self
,
a
:
Application
)
->
None
:
def
add_app
(
self
,
a
:
app
.
Application
)
->
None
:
self
.
applications
.
append
(
a
)
...
...
@@ -55,27 +56,42 @@ class FullSystemHost(Host):
self
.
cpu_freq
=
'3GHz'
self
.
disks
:
list
[
disk_images
.
DiskImage
]
=
[]
def
add_disk
(
self
,
disk
:
DiskImage
)
->
None
:
def
add_disk
(
self
,
disk
:
disk_images
.
DiskImage
)
->
None
:
self
.
disks
.
append
(
disk
)
class
LinuxHost
(
FullSystemHost
):
class
Base
LinuxHost
(
FullSystemHost
):
def
__init__
(
self
,
s
:
base
.
System
)
->
None
:
super
().
__init__
(
s
)
self
.
applications
:
list
[
LinuxApplication
]
=
[]
self
.
applications
:
list
[
app
.
Base
LinuxApplication
]
=
[]
self
.
load_modules
=
[]
self
.
kcmd_append
=
''
def
add_app
(
self
,
a
:
LinuxApplication
)
->
None
:
def
add_app
(
self
,
a
:
app
.
Base
LinuxApplication
)
->
None
:
self
.
applications
.
append
(
a
)
def
_concat_app_cmds
(
self
,
env
:
expenv
.
ExpEnv
,
mapper
:
tp
.
Callable
[[
app
.
LinuxApplication
,
expenv
.
ExpEnv
],
list
[
str
]]
)
->
list
[
str
]:
"""
Generate command list from applications by applying `mapper` to each
application on this host and concatenating the commands.
"""
cmds
=
[]
for
app
in
self
.
applications
:
cmds
+=
mapper
(
app
,
env
)
return
cmds
def
run_cmds
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
"""Commands to run on node."""
return
self
.
app
.
run_cmds
(
self
)
return
self
.
_concat_app_cmds
(
env
,
app
.
LinuxApplication
.
run_cmds
)
def
cleanup_cmds
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
"""Commands to run to cleanup node."""
return
[]
return
self
.
_concat_app_cmds
(
env
,
app
.
LinuxApplication
.
cleanup_cmds
)
def
config_files
(
self
,
env
:
expenv
.
ExpEnv
)
->
dict
[
str
,
tp
.
IO
]:
"""
...
...
@@ -92,17 +108,24 @@ class LinuxHost(FullSystemHost):
def
prepare_pre_cp
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
"""Commands to run to prepare node before checkpointing."""
return
[
'set -x'
,
'export HOME=/root'
,
'export LANG=en_US'
,
'export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:'
+
\
'/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"'
]
self
.
_concat_app_cmds
(
env
,
app
.
LinuxApplication
.
prepare_pre_cp
)
def
prepare_post_cp
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
"""Commands to run to prepare node after checkpoint restore."""
return
[]
return
self
.
_concat_app_cmds
(
env
,
app
.
LinuxApplication
.
prepare_post_cp
)
def
_config_str
(
self
,
env
:
expenv
.
ExpEnv
)
->
str
:
if
env
.
create_cp
:
sim
=
env
.
exp
.
get_simulator
(
self
)
cp_cmd
=
self
.
checkpoint_commands
()
else
:
cp_cmd
=
[]
es
=
self
.
prepare_pre_cp
(
env
)
+
self
.
app
.
prepare_pre_cp
(
env
)
+
\
cp_cmd
+
\
self
.
prepare_post_cp
(
env
)
+
self
.
app
.
prepare_post_cp
(
env
)
+
\
self
.
run_cmds
()
+
self
.
cleanup_cmds
()
return
'
\n
'
.
join
(
es
)
def
strfile
(
self
,
s
:
str
)
->
io
.
BytesIO
:
"""
...
...
@@ -112,4 +135,71 @@ class LinuxHost(FullSystemHost):
Using this, you can create a file with the string as its content on the
simulated node.
"""
return
io
.
BytesIO
(
bytes
(
s
,
encoding
=
'UTF-8'
))
\ No newline at end of file
return
io
.
BytesIO
(
bytes
(
s
,
encoding
=
'UTF-8'
))
class
LinuxHost
(
BaseLinuxHost
):
def
__init__
(
self
,
sys
)
->
None
:
super
().
__init__
(
sys
)
self
.
drivers
:
list
[
str
]
=
[]
def
cleanup_cmds
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
return
super
().
cleanup_cmds
(
env
)
+
[
'poweroff -f'
]
def
prepare_pre_cp
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
"""Commands to run to prepare node before checkpointing."""
return
[
'set -x'
,
'export HOME=/root'
,
'export LANG=en_US'
,
'export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:'
+
\
'/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"'
]
+
super
().
prepare_pre_cp
(
env
)
def
prepare_post_cp
(
self
)
->
tp
.
List
[
str
]:
l
=
[]
for
d
in
self
.
drivers
:
if
d
[
0
]
==
'/'
:
l
.
append
(
f
'insmod
{
d
}
'
)
else
:
l
.
append
(
f
'modprobe
{
d
}
'
)
eth_i
=
0
for
i
in
self
.
interfaces
():
# Get ifname parameter if set, otherwise default to ethX
if
'ifname'
in
i
.
parameters
:
ifn
=
i
.
parameters
[
'ifname'
]
elif
isinstance
(
i
,
eth
.
EthSimpleNIC
):
ifn
=
f
'eth
{
eth_i
}
'
eth_i
+=
1
else
:
continue
# Force MAC if requested
if
'force_mac_addr'
in
i
.
parameters
:
l
.
append
(
f
'ip link set dev
{
ifn
}
address '
f
'
{
i
.
parameters
[
'force_mac_addr'
]
}
'
)
# Bring interface up
l
.
append
(
f
'ip link set dev
{
ifn
}
up'
)
# Add IP addresses if included
if
'ipv4_addrs'
in
i
.
parameters
:
for
a
in
i
.
parameters
[
'ipv4_addrs'
]:
l
.
append
(
f
'ip addr add
{
a
}
dev
{
ifn
}
'
)
return
super
().
prepare_post_cp
()
+
l
class
I40ELinuxHost
(
LinuxHost
):
def
__init__
(
self
,
sys
)
->
None
:
super
().
__init__
(
sys
)
self
.
drivers
.
append
(
'i40e'
)
class
CorundumLinuxHost
(
LinuxHost
):
def
__init__
(
self
,
sys
)
->
None
:
super
().
__init__
(
sys
)
self
.
drivers
.
append
(
'/tmp/guest/mqnic.ko'
)
def
config_files
(
self
,
env
:
expenv
.
ExpEnv
)
->
tp
.
Dict
[
str
,
tp
.
IO
]:
m
=
{
'mqnic.ko'
:
open
(
'../images/mqnic/mqnic.ko'
,
'rb'
)}
return
{
**
m
,
**
super
().
config_files
()}
\ No newline at end of file
experiments/simbricks/orchestration/system/host/disk_images.py
View file @
a5a1ff28
...
...
@@ -21,13 +21,15 @@
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import
abc
import
io
import
os.path
import
tarfile
from
simbricks.orchestration.system.host
import
base
from
simbricks.orchestration.experiment
import
experiment_environment
as
expenv
class
DiskImage
(
abc
.
ABC
):
def
__init__
(
self
,
h
:
host
.
Host
)
->
None
:
def
__init__
(
self
,
h
:
base
.
Host
)
->
None
:
self
.
host
=
h
@
abc
.
abstractmethod
...
...
@@ -41,7 +43,7 @@ class DiskImage(abc.ABC):
# Disk image where user just provides a path
class
ExternalDiskImage
(
DiskImage
):
def
__init__
(
self
,
h
:
host
.
FullSystemHost
,
path
:
str
)
->
None
:
def
__init__
(
self
,
h
:
base
.
FullSystemHost
,
path
:
str
)
->
None
:
super
().
__init__
(
h
)
self
.
path
=
path
self
.
formats
=
[
"raw"
,
"qcow2"
]
...
...
@@ -56,7 +58,7 @@ class ExternalDiskImage(DiskImage):
# Disk images shipped with simbricks
class
DistroDiskImage
(
DiskImage
):
def
__init__
(
self
,
h
:
host
.
FullSystemHost
,
name
:
str
)
->
None
:
def
__init__
(
self
,
h
:
base
.
FullSystemHost
,
name
:
str
)
->
None
:
super
().
__init__
(
h
)
self
.
name
=
name
self
.
formats
=
[
"raw"
,
"qcow2"
]
...
...
@@ -78,22 +80,44 @@ class DistroDiskImage(DiskImage):
# Builds the Tar with the commands to run etc.
class
LinuxConfigDiskImage
(
DiskImage
):
def
__init__
(
self
,
h
:
host
.
LinuxHost
)
->
None
:
def
__init__
(
self
,
h
:
base
.
LinuxHost
)
->
None
:
super
().
__init__
(
h
)
self
.
host
:
base
.
LinuxHost
def
available_formats
(
self
)
->
list
[
str
]:
return
[
"raw"
]
async
def
prepare_image_path
(
self
,
env
:
expenv
.
ExpEnv
,
format
:
str
)
->
str
:
# TODO: build tar from host path parameters and then return path
pass
path
=
env
.
dynamic_img_path
(
self
,
format
)
with
tarfile
.
open
(
path
,
'w:'
)
as
tar
:
# add main run script
cfg_i
=
tarfile
.
TarInfo
(
'guest/run.sh'
)
cfg_i
.
mode
=
0o777
cfg_f
=
self
.
host
.
strfile
(
self
.
host
.
config_str
())
cfg_f
.
seek
(
0
,
io
.
SEEK_END
)
cfg_i
.
size
=
cfg_f
.
tell
()
cfg_f
.
seek
(
0
,
io
.
SEEK_SET
)
tar
.
addfile
(
tarinfo
=
cfg_i
,
fileobj
=
cfg_f
)
cfg_f
.
close
()
# add additional config files
for
(
n
,
f
)
in
self
.
host
.
config_files
(
env
).
items
():
f_i
=
tarfile
.
TarInfo
(
'guest/'
+
n
)
f_i
.
mode
=
0o777
f
.
seek
(
0
,
io
.
SEEK_END
)
f_i
.
size
=
f
.
tell
()
f
.
seek
(
0
,
io
.
SEEK_SET
)
tar
.
addfile
(
tarinfo
=
f_i
,
fileobj
=
f
)
f
.
close
()
# This is an additional example: building disk images directly from python
# Could of course also have a version that generates the packer config from
# python
class
PackerDiskImage
(
DiskImage
):
def
__init__
(
self
,
h
:
host
.
FullSystemHost
,
packer_config_path
:
str
)
->
None
:
def
__init__
(
self
,
h
:
base
.
FullSystemHost
,
packer_config_path
:
str
)
->
None
:
super
().
__init__
(
h
)
self
.
config_path
=
packer_config_path
...
...
gem5
@
8e4978a2
Compare
2c500a6a
...
8e4978a2
Subproject commit
2c500a6a7527a1305e1a8e03f53ea11e90b71b73
Subproject commit
8e4978a2ece997efa1fccb33e945c0c496587f34
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment