static uint32_t get_ring_buffer_size(void)
{ char ring_path[PATH_MAX];
DIR *dir; struct dirent *entry; struct stat st;
uint32_t ring_size = 0; int retry_count = 0;
/* Find the channel directory */
dir = opendir(FCOPY_CHANNELS_PATH); if (!dir) {
usleep(100 * 1000); /* Avoid race with kernel, wait 100ms and retry once */
dir = opendir(FCOPY_CHANNELS_PATH); if (!dir) {
syslog(LOG_ERR, "Failed to open channels directory: %s", strerror(errno)); return 0;
}
}
if (stat(ring_path, &st) == 0) { /* * stat returns size of Tx, Rx rings combined, * so take half of it for individual ring size.
*/
ring_size = (uint32_t)st.st_size / 2;
syslog(LOG_INFO, "Ring buffer size from %s: %u bytes",
ring_path, ring_size); break;
}
}
}
if (!ring_size && retry_count == 0) {
retry_count = 1;
rewinddir(dir);
usleep(100 * 1000); /* Wait 100ms and retry once */ goto retry_once;
}
closedir(dir);
if (!ring_size)
syslog(LOG_ERR, "Could not determine ring size");
staticbool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, unsignedchar *buf, unsignedint buflen, constint *fw_version, int fw_vercnt, constint *srv_version, int srv_vercnt, int *nego_fw_version, int *nego_srv_version)
{ int icframe_major, icframe_minor; int icmsg_major, icmsg_minor; int fw_major, fw_minor; int srv_major, srv_minor; int i, j; bool found_match = false; struct icmsg_negotiate *negop;
/* Check that there's enough space for icframe_vercnt, icmsg_vercnt */ if (buflen < ICMSG_HDR + offsetof(struct icmsg_negotiate, reserved)) {
syslog(LOG_ERR, "Invalid icmsg negotiate"); returnfalse;
}
/* * Respond with the framework and service * version numbers we can support.
*/
fw_error: if (!found_match) {
negop->icframe_vercnt = 0;
negop->icmsg_vercnt = 0;
} else {
negop->icframe_vercnt = 1;
negop->icmsg_vercnt = 1;
}
if (nego_fw_version)
*nego_fw_version = (icframe_major << 16) | icframe_minor;
if (nego_srv_version)
*nego_srv_version = (icmsg_major << 16) | icmsg_minor;
while (len < dest_size && *src) { if (src[len] < 0x80)
dest[len++] = (char)(*src++); else
dest[len++] = 'X';
}
dest[len] = '\0';
}
staticint hv_fcopy_start(struct hv_start_fcopy *smsg_in)
{ /* * file_name and path_name should have same length with appropriate * member of hv_start_fcopy.
*/ char file_name[W_MAX_PATH], path_name[W_MAX_PATH];
staticint hv_fcopy_send_data(struct hv_fcopy_hdr *fcopy_msg, int recvlen)
{ int operation = fcopy_msg->operation;
/* * The strings sent from the host are encoded in * utf16; convert it to utf8 strings. * The host assures us that the utf16 strings will not exceed * the max lengths specified. We will however, reserve room * for the string terminating character - in the utf16s_utf8s() * function we limit the size of the buffer where the converted * string is placed to W_MAX_PATH -1 to guarantee * that the strings can be properly terminated!
*/
switch (operation) { case START_FILE_COPY: return hv_fcopy_start((struct hv_start_fcopy *)fcopy_msg); case WRITE_TO_FILE: return hv_copy_data((struct hv_do_fcopy *)fcopy_msg); case COMPLETE_FCOPY: return hv_copy_finished();
}
return HV_E_FAIL;
}
/* process the packet recv from host */ staticint fcopy_pkt_process(struct vmbus_br *txbr)
{ int ret, offset, pktlen; int fcopy_srv_version; conststruct vmbus_chanpkt_hdr *pkt; struct hv_fcopy_hdr *fcopy_msg; struct icmsg_hdr *icmsghdr;
while (1) { /* * In this loop we process fcopy messages after the * handshake is complete.
*/
ret = pread(fcopy_fd, &tmp, sizeof(int), 0); if (ret < 0) { if (errno == EINTR || errno == EAGAIN) continue;
syslog(LOG_ERR, "pread failed: %s", strerror(errno)); goto close;
}
len = ring_size;
ret = rte_vmbus_chan_recv_raw(&rxbr, desc, &len); if (unlikely(ret <= 0)) { /* This indicates a failure to communicate (or worse) */
syslog(LOG_ERR, "VMBus channel recv error: %d", ret);
} else {
ret = fcopy_pkt_process(&txbr); if (ret < 0) goto close;
/* Signal host */ if ((write(fcopy_fd, &tmp, sizeof(int))) != sizeof(int)) {
ret = errno;
syslog(LOG_ERR, "Signal to host failed: %s\n", strerror(ret)); goto close;
}
}
}
close:
close(fcopy_fd);
free_desc:
free(desc); exit: return ret;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.