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
"vscode:/vscode.git/clone" did not exist on "da113364dff2f52cc26690d617d766272ed643ca"
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:
...
@@ -36,6 +36,7 @@ class System:
class
Component
(
abc
.
ABC
):
class
Component
(
abc
.
ABC
):
def
__init__
(
self
,
s
:
System
)
->
None
:
def
__init__
(
self
,
s
:
System
)
->
None
:
s
.
system
=
s
s
.
system
=
s
s
.
parameters
=
{}
s
.
add_component
(
self
)
s
.
add_component
(
self
)
@
abc
.
abstractmethod
@
abc
.
abstractmethod
...
...
experiments/simbricks/orchestration/system/host/app.py
View file @
a5a1ff28
...
@@ -34,17 +34,24 @@ class Application(abc.ABC):
...
@@ -34,17 +34,24 @@ class Application(abc.ABC):
# Note AK: Maybe we can factor most of the duplicate calls with the host out
# Note AK: Maybe we can factor most of the duplicate calls with the host out
# into a separate module.
# into a separate module.
class
LinuxApplication
(
abc
.
ABC
):
class
Base
LinuxApplication
(
abc
.
ABC
):
def
__init__
(
self
,
h
:
base
.
LinuxHost
)
->
None
:
def
__init__
(
self
,
h
:
base
.
LinuxHost
)
->
None
:
self
.
host
=
h
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
]:
def
run_cmds
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
"""Commands to run on node."""
"""Commands to run on node."""
return
self
.
app
.
run_cmds
(
self
)
pass
def
cleanup_cmds
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
def
cleanup_cmds
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
"""Commands to run to cleanup node."""
"""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
]:
def
config_files
(
self
,
env
:
expenv
.
ExpEnv
)
->
dict
[
str
,
tp
.
IO
]:
"""
"""
...
@@ -68,7 +75,10 @@ class LinuxApplication(abc.ABC):
...
@@ -68,7 +75,10 @@ class LinuxApplication(abc.ABC):
def
prepare_post_cp
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
def
prepare_post_cp
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
"""Commands to run to prepare node after checkpoint restore."""
"""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
:
def
strfile
(
self
,
s
:
str
)
->
io
.
BytesIO
:
"""
"""
...
@@ -79,3 +89,48 @@ class LinuxApplication(abc.ABC):
...
@@ -79,3 +89,48 @@ class LinuxApplication(abc.ABC):
simulated node.
simulated node.
"""
"""
return
io
.
BytesIO
(
bytes
(
s
,
encoding
=
"UTF-8"
))
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 @@
...
@@ -23,6 +23,7 @@
import
typing
as
tp
import
typing
as
tp
import
io
import
io
from
os
import
path
from
os
import
path
from
simbricks.orchestration.experiment
import
experiment_environment
as
expenv
from
simbricks.orchestration.system
import
base
from
simbricks.orchestration.system
import
base
from
simbricks.orchestration.system
import
eth
from
simbricks.orchestration.system
import
eth
from
simbricks.orchestration.system
import
mem
from
simbricks.orchestration.system
import
mem
...
@@ -34,8 +35,8 @@ from simbricks.orchestration.system.host import app
...
@@ -34,8 +35,8 @@ from simbricks.orchestration.system.host import app
class
Host
(
base
.
Component
):
class
Host
(
base
.
Component
):
def
__init__
(
self
,
s
:
base
.
System
):
def
__init__
(
self
,
s
:
base
.
System
):
super
().
__init__
(
s
)
super
().
__init__
(
s
)
self
.
ifs
:
list
[
pcie
.
PCIeHost
Interface
]
=
[]
self
.
ifs
:
list
[
base
.
Interface
]
=
[]
self
.
applications
:
list
[
Application
]
self
.
applications
:
list
[
app
.
Application
]
def
interfaces
(
self
)
->
list
[
base
.
Interface
]:
def
interfaces
(
self
)
->
list
[
base
.
Interface
]:
return
self
.
pcie_ifs
+
self
.
eth_ifs
+
self
.
mem_ifs
return
self
.
pcie_ifs
+
self
.
eth_ifs
+
self
.
mem_ifs
...
@@ -43,7 +44,7 @@ class Host(base.Component):
...
@@ -43,7 +44,7 @@ class Host(base.Component):
def
add_if
(
self
,
i
:
base
.
Interface
)
->
None
:
def
add_if
(
self
,
i
:
base
.
Interface
)
->
None
:
self
.
ifs
.
append
(
i
)
self
.
ifs
.
append
(
i
)
def
add_app
(
self
,
a
:
Application
)
->
None
:
def
add_app
(
self
,
a
:
app
.
Application
)
->
None
:
self
.
applications
.
append
(
a
)
self
.
applications
.
append
(
a
)
...
@@ -55,27 +56,42 @@ class FullSystemHost(Host):
...
@@ -55,27 +56,42 @@ class FullSystemHost(Host):
self
.
cpu_freq
=
'3GHz'
self
.
cpu_freq
=
'3GHz'
self
.
disks
:
list
[
disk_images
.
DiskImage
]
=
[]
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
)
self
.
disks
.
append
(
disk
)
class
LinuxHost
(
FullSystemHost
):
class
Base
LinuxHost
(
FullSystemHost
):
def
__init__
(
self
,
s
:
base
.
System
)
->
None
:
def
__init__
(
self
,
s
:
base
.
System
)
->
None
:
super
().
__init__
(
s
)
super
().
__init__
(
s
)
self
.
applications
:
list
[
LinuxApplication
]
=
[]
self
.
applications
:
list
[
app
.
Base
LinuxApplication
]
=
[]
self
.
load_modules
=
[]
self
.
load_modules
=
[]
self
.
kcmd_append
=
''
self
.
kcmd_append
=
''
def
add_app
(
self
,
a
:
LinuxApplication
)
->
None
:
def
add_app
(
self
,
a
:
app
.
Base
LinuxApplication
)
->
None
:
self
.
applications
.
append
(
a
)
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
]:
def
run_cmds
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
"""Commands to run on node."""
"""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
]:
def
cleanup_cmds
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
"""Commands to run to cleanup node."""
"""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
]:
def
config_files
(
self
,
env
:
expenv
.
ExpEnv
)
->
dict
[
str
,
tp
.
IO
]:
"""
"""
...
@@ -92,17 +108,24 @@ class LinuxHost(FullSystemHost):
...
@@ -92,17 +108,24 @@ class LinuxHost(FullSystemHost):
def
prepare_pre_cp
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
def
prepare_pre_cp
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
"""Commands to run to prepare node before checkpointing."""
"""Commands to run to prepare node before checkpointing."""
return
[
self
.
_concat_app_cmds
(
env
,
app
.
LinuxApplication
.
prepare_pre_cp
)
'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"'
]
def
prepare_post_cp
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
def
prepare_post_cp
(
self
,
env
:
expenv
.
ExpEnv
)
->
list
[
str
]:
"""Commands to run to prepare node after checkpoint restore."""
"""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
:
def
strfile
(
self
,
s
:
str
)
->
io
.
BytesIO
:
"""
"""
...
@@ -112,4 +135,71 @@ class LinuxHost(FullSystemHost):
...
@@ -112,4 +135,71 @@ class LinuxHost(FullSystemHost):
Using this, you can create a file with the string as its content on the
Using this, you can create a file with the string as its content on the
simulated node.
simulated node.
"""
"""
return
io
.
BytesIO
(
bytes
(
s
,
encoding
=
'UTF-8'
))
return
io
.
BytesIO
(
bytes
(
s
,
encoding
=
'UTF-8'
))
\ No newline at end of file
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 @@
...
@@ -21,13 +21,15 @@
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import
abc
import
abc
import
io
import
os.path
import
os.path
import
tarfile
from
simbricks.orchestration.system.host
import
base
from
simbricks.orchestration.system.host
import
base
from
simbricks.orchestration.experiment
import
experiment_environment
as
expenv
from
simbricks.orchestration.experiment
import
experiment_environment
as
expenv
class
DiskImage
(
abc
.
ABC
):
class
DiskImage
(
abc
.
ABC
):
def
__init__
(
self
,
h
:
host
.
Host
)
->
None
:
def
__init__
(
self
,
h
:
base
.
Host
)
->
None
:
self
.
host
=
h
self
.
host
=
h
@
abc
.
abstractmethod
@
abc
.
abstractmethod
...
@@ -41,7 +43,7 @@ class DiskImage(abc.ABC):
...
@@ -41,7 +43,7 @@ class DiskImage(abc.ABC):
# Disk image where user just provides a path
# Disk image where user just provides a path
class
ExternalDiskImage
(
DiskImage
):
class
ExternalDiskImage
(
DiskImage
):
def
__init__
(
self
,
h
:
host
.
FullSystemHost
,
path
:
str
)
->
None
:
def
__init__
(
self
,
h
:
base
.
FullSystemHost
,
path
:
str
)
->
None
:
super
().
__init__
(
h
)
super
().
__init__
(
h
)
self
.
path
=
path
self
.
path
=
path
self
.
formats
=
[
"raw"
,
"qcow2"
]
self
.
formats
=
[
"raw"
,
"qcow2"
]
...
@@ -56,7 +58,7 @@ class ExternalDiskImage(DiskImage):
...
@@ -56,7 +58,7 @@ class ExternalDiskImage(DiskImage):
# Disk images shipped with simbricks
# Disk images shipped with simbricks
class
DistroDiskImage
(
DiskImage
):
class
DistroDiskImage
(
DiskImage
):
def
__init__
(
self
,
h
:
host
.
FullSystemHost
,
name
:
str
)
->
None
:
def
__init__
(
self
,
h
:
base
.
FullSystemHost
,
name
:
str
)
->
None
:
super
().
__init__
(
h
)
super
().
__init__
(
h
)
self
.
name
=
name
self
.
name
=
name
self
.
formats
=
[
"raw"
,
"qcow2"
]
self
.
formats
=
[
"raw"
,
"qcow2"
]
...
@@ -78,22 +80,44 @@ class DistroDiskImage(DiskImage):
...
@@ -78,22 +80,44 @@ class DistroDiskImage(DiskImage):
# Builds the Tar with the commands to run etc.
# Builds the Tar with the commands to run etc.
class
LinuxConfigDiskImage
(
DiskImage
):
class
LinuxConfigDiskImage
(
DiskImage
):
def
__init__
(
self
,
h
:
host
.
LinuxHost
)
->
None
:
def
__init__
(
self
,
h
:
base
.
LinuxHost
)
->
None
:
super
().
__init__
(
h
)
super
().
__init__
(
h
)
self
.
host
:
base
.
LinuxHost
def
available_formats
(
self
)
->
list
[
str
]:
def
available_formats
(
self
)
->
list
[
str
]:
return
[
"raw"
]
return
[
"raw"
]
async
def
prepare_image_path
(
self
,
env
:
expenv
.
ExpEnv
,
format
:
str
)
->
str
:
async
def
prepare_image_path
(
self
,
env
:
expenv
.
ExpEnv
,
format
:
str
)
->
str
:
# TODO: build tar from host path parameters and then return path
# 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
# This is an additional example: building disk images directly from python
# Could of course also have a version that generates the packer config from
# Could of course also have a version that generates the packer config from
# python
# python
class
PackerDiskImage
(
DiskImage
):
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
)
super
().
__init__
(
h
)
self
.
config_path
=
packer_config_path
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