-
Notifications
You must be signed in to change notification settings - Fork 30
mctpd: Send Discovery Notify on Endpoint role set #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,11 +22,16 @@ async def iface(): | |
|
||
|
||
@pytest.fixture | ||
async def sysnet(iface): | ||
async def bo(iface): | ||
return Endpoint(iface, bytes([0x10]), eid=8) | ||
|
||
|
||
@pytest.fixture | ||
async def sysnet(iface, bo): | ||
system = System() | ||
await system.add_interface(iface) | ||
network = Network() | ||
network.add_endpoint(Endpoint(iface, bytes([0x10]), eid=8)) | ||
network.add_endpoint(bo) | ||
return Sysnet(system, network) | ||
|
||
|
||
|
@@ -113,12 +118,37 @@ class TestDiscovery: | |
async def iface(self): | ||
return System.Interface("mctp0", 1, 1, bytes([0x1D]), 68, 254, True, PhysicalBinding.PCIE_VDM) | ||
|
||
@pytest.fixture | ||
async def bo(self, iface): | ||
return TestDiscovery.BusOwnerEndpoint(iface, bytes([0x00]), eid=8) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I might need to add support for other routing type here like broadcast, or specific route-to-root-complex type inside There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we could just add a method to Endpoint, something like: class PCIeEndpoint:
...
def lladdr_matches(self, lladdr):
return lladdr == self.ROUTE_TO_RC_LLADDR which, if defined, would allow Would that work? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, extending that in |
||
|
||
|
||
class BusOwnerEndpoint(Endpoint): | ||
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
self.sem = trio.Semaphore(initial_value=0) | ||
|
||
async def handle_mctp_control(self, sock, addr, data): | ||
print(addr, data) | ||
flags, opcode = data[0:2] | ||
if opcode != 0x0D: | ||
return await super().handle_mctp_control(sock, addr, data) | ||
dst_addr = MCTPSockAddr.for_ep_resp(self, addr, sock.addr_ext) | ||
await sock.send(dst_addr, bytes([flags & 0x1F, opcode, 0x00])) | ||
self.sem.release() | ||
|
||
|
||
""" Test simple Discovery sequence """ | ||
async def test_simple_discovery_sequence(self, dbus, mctpd): | ||
bo = mctpd.network.endpoints[0] | ||
|
||
assert len(mctpd.system.addresses) == 0 | ||
|
||
# BMC should send a Discovery Notify message | ||
with trio.move_on_after(5) as expected: | ||
await bo.sem.acquire() | ||
assert not expected.cancelled_caught | ||
|
||
# no EID yet | ||
rsp = await bo.send_control(mctpd.network.mctp_socket, MCTPControlCommand(True, 0, 0x02)) | ||
assert rsp.hex(' ') == '00 02 00 00 02 00' | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I generally am not happy with this for two reasons:
mctp_ops.timeout()
..., and then use some existing pytest or trio time support.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I'd like to implement time control through the ops interface; it'd just be a
get_time()
(or similar) callback; mctpd would then use that to set the poll timeouts (as it does currently, just with no callback).Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no wait, that might be a bit more complex with the
sd_event
bits, let me check it out in more detail.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if I understand you correctly, but do you mean keeping track of timers inside
mctpd
itself?Something like libcurl multi interface, where you decide when to call
curl_multi_socket_action
(could be repeatedly in a loop, or efficiently by polling I/O outside), and then the library double-checks if time elapsed is enough to trigger some timeouts, or sockets are ready to be read/recv/... Or something like quiche, where there are no I/O inside the core library, the OS-specific wrapper application does all I/O related to time and socket.I see we are using two timers:
Recovery/Discovery timer: Since we are using callbacks anyway, I assume converting to the above style is not that much of a hassle. Have a list of timeout and callback, and check elapsed time then callback() on our own.
Socket receive timeout: I assume we could sidestep this by adding
SO_RCVTIMEO
and keep the blocking I/O, at the cost of introducing more paths related to time. Alternately, we could convert everything into callbacks, which... should require major reworks since all paths are now deconstructed into callbacks and state machines. Otherwise, I don't have much experience on how async C should be written (or perhaps... threads/threadpool instead of single thread event loop)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking something more along the (high-level) lines of:
this would be fairly straightforward if we were using poll() (and friends) directly, and could hook at that layer, but i can't (after only some cursory research) seem to see a facility to do this with sd_event, without some awful hacks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that said, our usage of sd_event timers is pretty minimal, maybe I can mock that...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i am currently committing crimes against
sd_event