Introduce FCOPY_VERSION_1 to support kernel replying to the negotiation message with its own version.
Unified · Split
| @@ -62,6 +62,10 @@ static DECLARE_WORK(fcopy_send_work, fcopy_send_data); · 61 unmodified lines | |||
| 62 | static const char fcopy_devname[] = "vmbus/hv_fcopy"; | 62 | static const char fcopy_devname[] = "vmbus/hv_fcopy"; |
| 63 | static u8 *recv_buffer; | 63 | static u8 *recv_buffer; |
| 64 | static struct hvutil_transport *hvt; | 64 | static struct hvutil_transport *hvt; |
| 65 | /* | ||
| 66 | * This state maintains the version number registered by the daemon. | ||
| 67 | */ | ||
| 68 | static int dm_reg_value; | ||
| 65 | 69 | ||
| 66 | static void fcopy_timeout_func(struct work_struct *dummy) | 70 | static void fcopy_timeout_func(struct work_struct *dummy) |
| 67 | { | 71 | { |
| @@ -81,8 +85,18 @@ static void fcopy_timeout_func(struct work_struct *dummy) · 13 unmodified lines | |||
| 81 | 85 | ||
| 82 | static int fcopy_handle_handshake(u32 version) | 86 | static int fcopy_handle_handshake(u32 version) |
| 83 | { | 87 | { |
| 88 | u32 our_ver = FCOPY_CURRENT_VERSION; | ||
| 89 | |||
| 84 | switch (version) { | 90 | switch (version) { |
| 85 | case FCOPY_CURRENT_VERSION: | 91 | case FCOPY_VERSION_0: |
| 92 | /* Daemon doesn't expect us to reply */ | ||
| 93 | dm_reg_value = version; | ||
| 94 | break; | ||
| 95 | case FCOPY_VERSION_1: | ||
| 96 | /* Daemon expects us to reply with our own version */ | ||
| 97 | if (hvutil_transport_send(hvt, &our_ver, sizeof(our_ver))) | ||
| 98 | return -EFAULT; | ||
| 99 | dm_reg_value = version; | ||
| 86 | break; | 100 | break; |
| 87 | default: | 101 | default: |
| 88 | /* | 102 | /* |
| @@ -105,7 +105,8 @@ struct hv_vss_msg { · 104 unmodified lines | |||
| 105 | */ | 105 | */ |
| 106 | 106 | ||
| 107 | #define FCOPY_VERSION_0 0 | 107 | #define FCOPY_VERSION_0 0 |
| 108 | #define FCOPY_CURRENT_VERSION FCOPY_VERSION_0 | 108 | #define FCOPY_VERSION_1 1 |
| 109 | #define FCOPY_CURRENT_VERSION FCOPY_VERSION_1 | ||
| 109 | #define W_MAX_PATH 260 | 110 | #define W_MAX_PATH 260 |
| 110 | 111 | ||
| 111 | enum hv_fcopy_op { | 112 | enum hv_fcopy_op { |
| @@ -137,6 +137,8 @@ int main(int argc, char *argv[]) · 136 unmodified lines | |||
| 137 | int version = FCOPY_CURRENT_VERSION; | 137 | int version = FCOPY_CURRENT_VERSION; |
| 138 | char *buffer[4096 * 2]; | 138 | char *buffer[4096 * 2]; |
| 139 | struct hv_fcopy_hdr *in_msg; | 139 | struct hv_fcopy_hdr *in_msg; |
| 140 | int in_handshake = 1; | ||
| 141 | __u32 kernel_modver; | ||
| 140 | 142 | ||
| 141 | static struct option long_options[] = { | 143 | static struct option long_options[] = { |
| 142 | {"help", no_argument, 0, 'h' }, | 144 | {"help", no_argument, 0, 'h' }, |
| @@ -191,6 +193,19 @@ int main(int argc, char *argv[]) · 48 unmodified lines | |||
| 191 | syslog(LOG_ERR, "pread failed: %s", strerror(errno)); | 193 | syslog(LOG_ERR, "pread failed: %s", strerror(errno)); |
| 192 | exit(EXIT_FAILURE); | 194 | exit(EXIT_FAILURE); |
| 193 | } | 195 | } |
| 196 | |||
| 197 | if (in_handshake) { | ||
| 198 | if (len != sizeof(kernel_modver)) { | ||
| 199 | syslog(LOG_ERR, "invalid version negotiation"); | ||
| 200 | exit(EXIT_FAILURE); | ||
| 201 | } | ||
| 202 | kernel_modver = *(__u32 *)buffer; | ||
| 203 | in_handshake = 0; | ||
| 204 | syslog(LOG_INFO, "HV_FCOPY: kernel module version: %d", | ||
| 205 | kernel_modver); | ||
| 206 | continue; | ||
| 207 | } | ||
| 208 | |||
| 194 | in_msg = (struct hv_fcopy_hdr *)buffer; | 209 | in_msg = (struct hv_fcopy_hdr *)buffer; |
| 195 | 210 | ||
| 196 | switch (in_msg->operation) { | 211 | switch (in_msg->operation) { |