Skip to content
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

sendto not working as expected #131

Open
gz opened this issue Mar 19, 2019 · 1 comment
Open

sendto not working as expected #131

gz opened this issue Mar 19, 2019 · 1 comment

Comments

@gz
Copy link

gz commented Mar 19, 2019

I'm running rumprun on qemu (hw target) using e1000 (wm0, configured with DHCP) with the following code snippet:

// A: sched_yield();
char buf[64];
pkt_sent = 0;
while (pkt_sent < 3) {
    sprintf(buf, "pkt %zu\n", pkt_sent);
    if (sendto(fd, buf, strlen(buf)+1, 0, dst, sizeof(struct sockaddr_in)) >= 0)
        pkt_sent++;
    else {
        printf("errno %d: %s\n", errno, strerror(errno));
        exit(1);
    }
    // B: sched_yield();
}
// C: sched_yield();

On the receiver (listening on a tap device) I get the following output:

pkt 2

With the same code on Linux I see the following 3 messages on the receiver socket:

pkt 0
pkt 1
pkt 2

With uncommenting sched_yield calls I see the following outputs:

Unikernel (uncomment line A):

pkt 2

Unikernel (uncomment line B):

pkt 1
pkt 2

Unikernel (uncomment line C):

pkt 2

Unikernel (uncomment line A,B,C):

pkt 1
pkt 2

I have the following questions to help my understanding of the cooperative scheduling model:

  • How do I send pkt 0 with the unikernel?
  • Is there a better way to send multiple packets without inserting calls to sched_yield (e.g., will a proper poll/select loop etc. take care of this?)
  • Is it a bug that sendto() does not return with an error, even though the message for pkt 0 was never sent?
@ljluestc
Copy link

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sched.h> // Include sched_yield
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <poll.h>

int main() {
    int fd;
    struct sockaddr_in dst;
    // Initialize socket and destination address (omitted for brevity)

    char buf[64];
    size_t pkt_sent = 0;
    struct pollfd pfd;
    pfd.fd = fd;
    pfd.events = POLLOUT; // We are interested in writing

    while (pkt_sent < 3) {
        sprintf(buf, "pkt %zu\n", pkt_sent);
        int ret = poll(&pfd, 1, 1000); // 1 second timeout
        if (ret > 0) {
            if (pfd.revents & POLLOUT) {
                if (sendto(fd, buf, strlen(buf)+1, 0, (struct sockaddr *)&dst, sizeof(dst)) >= 0) {
                    pkt_sent++;
                } else {
                    printf("errno %d: %s\n", errno, strerror(errno));
                    exit(1);
                }
            }
        } else if (ret == 0) {
            printf("Timeout waiting for socket to be ready\n");
        } else {
            printf("poll error: %s\n", strerror(errno));
            exit(1);
        }
    }

    return 0;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants