hv_kvp.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. /*
  2. * An implementation of key value pair (KVP) functionality for Linux.
  3. *
  4. *
  5. * Copyright (C) 2010, Novell, Inc.
  6. * Author : K. Y. Srinivasan <ksrinivasan@novell.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License version 2 as published
  10. * by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  15. * NON INFRINGEMENT. See the GNU General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21. *
  22. */
  23. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  24. #include <linux/net.h>
  25. #include <linux/nls.h>
  26. #include <linux/connector.h>
  27. #include <linux/workqueue.h>
  28. #include <linux/hyperv.h>
  29. /*
  30. * Global state maintained for transaction that is being processed.
  31. * Note that only one transaction can be active at any point in time.
  32. *
  33. * This state is set when we receive a request from the host; we
  34. * cleanup this state when the transaction is completed - when we respond
  35. * to the host with the key value.
  36. */
  37. static struct {
  38. bool active; /* transaction status - active or not */
  39. int recv_len; /* number of bytes received. */
  40. struct hv_kvp_msg *kvp_msg; /* current message */
  41. struct vmbus_channel *recv_channel; /* chn we got the request */
  42. u64 recv_req_id; /* request ID. */
  43. void *kvp_context; /* for the channel callback */
  44. } kvp_transaction;
  45. /*
  46. * Before we can accept KVP messages from the host, we need
  47. * to handshake with the user level daemon. This state tracks
  48. * if we are in the handshake phase.
  49. */
  50. static bool in_hand_shake = true;
  51. /*
  52. * This state maintains the version number registered by the daemon.
  53. */
  54. static int dm_reg_value;
  55. static void kvp_send_key(struct work_struct *dummy);
  56. static void kvp_respond_to_host(struct hv_kvp_msg *msg, int error);
  57. static void kvp_work_func(struct work_struct *dummy);
  58. static void kvp_register(int);
  59. static DECLARE_DELAYED_WORK(kvp_work, kvp_work_func);
  60. static DECLARE_WORK(kvp_sendkey_work, kvp_send_key);
  61. static struct cb_id kvp_id = { CN_KVP_IDX, CN_KVP_VAL };
  62. static const char kvp_name[] = "kvp_kernel_module";
  63. static u8 *recv_buffer;
  64. /*
  65. * Register the kernel component with the user-level daemon.
  66. * As part of this registration, pass the LIC version number.
  67. */
  68. static void
  69. kvp_register(int reg_value)
  70. {
  71. struct cn_msg *msg;
  72. struct hv_kvp_msg *kvp_msg;
  73. char *version;
  74. msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg), GFP_ATOMIC);
  75. if (msg) {
  76. kvp_msg = (struct hv_kvp_msg *)msg->data;
  77. version = kvp_msg->body.kvp_register.version;
  78. msg->id.idx = CN_KVP_IDX;
  79. msg->id.val = CN_KVP_VAL;
  80. kvp_msg->kvp_hdr.operation = reg_value;
  81. strcpy(version, HV_DRV_VERSION);
  82. msg->len = sizeof(struct hv_kvp_msg);
  83. cn_netlink_send(msg, 0, GFP_ATOMIC);
  84. kfree(msg);
  85. }
  86. }
  87. static void
  88. kvp_work_func(struct work_struct *dummy)
  89. {
  90. /*
  91. * If the timer fires, the user-mode component has not responded;
  92. * process the pending transaction.
  93. */
  94. kvp_respond_to_host(NULL, HV_E_FAIL);
  95. }
  96. static int kvp_handle_handshake(struct hv_kvp_msg *msg)
  97. {
  98. int ret = 1;
  99. switch (msg->kvp_hdr.operation) {
  100. case KVP_OP_REGISTER:
  101. dm_reg_value = KVP_OP_REGISTER;
  102. pr_info("KVP: IP injection functionality not available\n");
  103. pr_info("KVP: Upgrade the KVP daemon\n");
  104. break;
  105. case KVP_OP_REGISTER1:
  106. dm_reg_value = KVP_OP_REGISTER1;
  107. break;
  108. default:
  109. pr_info("KVP: incompatible daemon\n");
  110. pr_info("KVP: KVP version: %d, Daemon version: %d\n",
  111. KVP_OP_REGISTER1, msg->kvp_hdr.operation);
  112. ret = 0;
  113. }
  114. if (ret) {
  115. /*
  116. * We have a compatible daemon; complete the handshake.
  117. */
  118. pr_info("KVP: user-mode registering done.\n");
  119. kvp_register(dm_reg_value);
  120. kvp_transaction.active = false;
  121. if (kvp_transaction.kvp_context)
  122. hv_kvp_onchannelcallback(kvp_transaction.kvp_context);
  123. }
  124. return ret;
  125. }
  126. /*
  127. * Callback when data is received from user mode.
  128. */
  129. static void
  130. kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
  131. {
  132. struct hv_kvp_msg *message;
  133. struct hv_kvp_msg_enumerate *data;
  134. int error = 0;
  135. message = (struct hv_kvp_msg *)msg->data;
  136. /*
  137. * If we are negotiating the version information
  138. * with the daemon; handle that first.
  139. */
  140. if (in_hand_shake) {
  141. if (kvp_handle_handshake(message))
  142. in_hand_shake = false;
  143. return;
  144. }
  145. /*
  146. * Based on the version of the daemon, we propagate errors from the
  147. * daemon differently.
  148. */
  149. data = &message->body.kvp_enum_data;
  150. switch (dm_reg_value) {
  151. case KVP_OP_REGISTER:
  152. /*
  153. * Null string is used to pass back error condition.
  154. */
  155. if (data->data.key[0] == 0)
  156. error = HV_S_CONT;
  157. break;
  158. case KVP_OP_REGISTER1:
  159. /*
  160. * We use the message header information from
  161. * the user level daemon to transmit errors.
  162. */
  163. error = message->error;
  164. break;
  165. }
  166. /*
  167. * Complete the transaction by forwarding the key value
  168. * to the host. But first, cancel the timeout.
  169. */
  170. if (cancel_delayed_work_sync(&kvp_work))
  171. kvp_respond_to_host(message, error);
  172. }
  173. static int process_ob_ipinfo(void *in_msg, void *out_msg, int op)
  174. {
  175. struct hv_kvp_msg *in = in_msg;
  176. struct hv_kvp_ip_msg *out = out_msg;
  177. int len;
  178. switch (op) {
  179. case KVP_OP_GET_IP_INFO:
  180. /*
  181. * Transform all parameters into utf16 encoding.
  182. */
  183. len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.ip_addr,
  184. strlen((char *)in->body.kvp_ip_val.ip_addr),
  185. UTF16_HOST_ENDIAN,
  186. (wchar_t *)out->kvp_ip_val.ip_addr,
  187. MAX_IP_ADDR_SIZE);
  188. if (len < 0)
  189. return len;
  190. len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.sub_net,
  191. strlen((char *)in->body.kvp_ip_val.sub_net),
  192. UTF16_HOST_ENDIAN,
  193. (wchar_t *)out->kvp_ip_val.sub_net,
  194. MAX_IP_ADDR_SIZE);
  195. if (len < 0)
  196. return len;
  197. len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.gate_way,
  198. strlen((char *)in->body.kvp_ip_val.gate_way),
  199. UTF16_HOST_ENDIAN,
  200. (wchar_t *)out->kvp_ip_val.gate_way,
  201. MAX_GATEWAY_SIZE);
  202. if (len < 0)
  203. return len;
  204. len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.dns_addr,
  205. strlen((char *)in->body.kvp_ip_val.dns_addr),
  206. UTF16_HOST_ENDIAN,
  207. (wchar_t *)out->kvp_ip_val.dns_addr,
  208. MAX_IP_ADDR_SIZE);
  209. if (len < 0)
  210. return len;
  211. len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.adapter_id,
  212. strlen((char *)in->body.kvp_ip_val.adapter_id),
  213. UTF16_HOST_ENDIAN,
  214. (wchar_t *)out->kvp_ip_val.adapter_id,
  215. MAX_IP_ADDR_SIZE);
  216. if (len < 0)
  217. return len;
  218. out->kvp_ip_val.dhcp_enabled =
  219. in->body.kvp_ip_val.dhcp_enabled;
  220. out->kvp_ip_val.addr_family =
  221. in->body.kvp_ip_val.addr_family;
  222. }
  223. return 0;
  224. }
  225. static void process_ib_ipinfo(void *in_msg, void *out_msg, int op)
  226. {
  227. struct hv_kvp_ip_msg *in = in_msg;
  228. struct hv_kvp_msg *out = out_msg;
  229. switch (op) {
  230. case KVP_OP_SET_IP_INFO:
  231. /*
  232. * Transform all parameters into utf8 encoding.
  233. */
  234. utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.ip_addr,
  235. MAX_IP_ADDR_SIZE,
  236. UTF16_LITTLE_ENDIAN,
  237. (__u8 *)out->body.kvp_ip_val.ip_addr,
  238. MAX_IP_ADDR_SIZE);
  239. utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.sub_net,
  240. MAX_IP_ADDR_SIZE,
  241. UTF16_LITTLE_ENDIAN,
  242. (__u8 *)out->body.kvp_ip_val.sub_net,
  243. MAX_IP_ADDR_SIZE);
  244. utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.gate_way,
  245. MAX_GATEWAY_SIZE,
  246. UTF16_LITTLE_ENDIAN,
  247. (__u8 *)out->body.kvp_ip_val.gate_way,
  248. MAX_GATEWAY_SIZE);
  249. utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.dns_addr,
  250. MAX_IP_ADDR_SIZE,
  251. UTF16_LITTLE_ENDIAN,
  252. (__u8 *)out->body.kvp_ip_val.dns_addr,
  253. MAX_IP_ADDR_SIZE);
  254. out->body.kvp_ip_val.dhcp_enabled = in->kvp_ip_val.dhcp_enabled;
  255. default:
  256. utf16s_to_utf8s((wchar_t *)in->kvp_ip_val.adapter_id,
  257. MAX_ADAPTER_ID_SIZE,
  258. UTF16_LITTLE_ENDIAN,
  259. (__u8 *)out->body.kvp_ip_val.adapter_id,
  260. MAX_ADAPTER_ID_SIZE);
  261. out->body.kvp_ip_val.addr_family = in->kvp_ip_val.addr_family;
  262. }
  263. }
  264. static void
  265. kvp_send_key(struct work_struct *dummy)
  266. {
  267. struct cn_msg *msg;
  268. struct hv_kvp_msg *message;
  269. struct hv_kvp_msg *in_msg;
  270. __u8 operation = kvp_transaction.kvp_msg->kvp_hdr.operation;
  271. __u8 pool = kvp_transaction.kvp_msg->kvp_hdr.pool;
  272. __u32 val32;
  273. __u64 val64;
  274. msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg) , GFP_ATOMIC);
  275. if (!msg)
  276. return;
  277. msg->id.idx = CN_KVP_IDX;
  278. msg->id.val = CN_KVP_VAL;
  279. message = (struct hv_kvp_msg *)msg->data;
  280. message->kvp_hdr.operation = operation;
  281. message->kvp_hdr.pool = pool;
  282. in_msg = kvp_transaction.kvp_msg;
  283. /*
  284. * The key/value strings sent from the host are encoded in
  285. * in utf16; convert it to utf8 strings.
  286. * The host assures us that the utf16 strings will not exceed
  287. * the max lengths specified. We will however, reserve room
  288. * for the string terminating character - in the utf16s_utf8s()
  289. * function we limit the size of the buffer where the converted
  290. * string is placed to HV_KVP_EXCHANGE_MAX_*_SIZE -1 to gaurantee
  291. * that the strings can be properly terminated!
  292. */
  293. switch (message->kvp_hdr.operation) {
  294. case KVP_OP_SET_IP_INFO:
  295. process_ib_ipinfo(in_msg, message, KVP_OP_SET_IP_INFO);
  296. break;
  297. case KVP_OP_GET_IP_INFO:
  298. process_ib_ipinfo(in_msg, message, KVP_OP_GET_IP_INFO);
  299. break;
  300. case KVP_OP_SET:
  301. switch (in_msg->body.kvp_set.data.value_type) {
  302. case REG_SZ:
  303. /*
  304. * The value is a string - utf16 encoding.
  305. */
  306. message->body.kvp_set.data.value_size =
  307. utf16s_to_utf8s(
  308. (wchar_t *)in_msg->body.kvp_set.data.value,
  309. in_msg->body.kvp_set.data.value_size,
  310. UTF16_LITTLE_ENDIAN,
  311. message->body.kvp_set.data.value,
  312. HV_KVP_EXCHANGE_MAX_VALUE_SIZE - 1) + 1;
  313. break;
  314. case REG_U32:
  315. /*
  316. * The value is a 32 bit scalar.
  317. * We save this as a utf8 string.
  318. */
  319. val32 = in_msg->body.kvp_set.data.value_u32;
  320. message->body.kvp_set.data.value_size =
  321. sprintf(message->body.kvp_set.data.value,
  322. "%d", val32) + 1;
  323. break;
  324. case REG_U64:
  325. /*
  326. * The value is a 64 bit scalar.
  327. * We save this as a utf8 string.
  328. */
  329. val64 = in_msg->body.kvp_set.data.value_u64;
  330. message->body.kvp_set.data.value_size =
  331. sprintf(message->body.kvp_set.data.value,
  332. "%llu", val64) + 1;
  333. break;
  334. }
  335. case KVP_OP_GET:
  336. message->body.kvp_set.data.key_size =
  337. utf16s_to_utf8s(
  338. (wchar_t *)in_msg->body.kvp_set.data.key,
  339. in_msg->body.kvp_set.data.key_size,
  340. UTF16_LITTLE_ENDIAN,
  341. message->body.kvp_set.data.key,
  342. HV_KVP_EXCHANGE_MAX_KEY_SIZE - 1) + 1;
  343. break;
  344. case KVP_OP_DELETE:
  345. message->body.kvp_delete.key_size =
  346. utf16s_to_utf8s(
  347. (wchar_t *)in_msg->body.kvp_delete.key,
  348. in_msg->body.kvp_delete.key_size,
  349. UTF16_LITTLE_ENDIAN,
  350. message->body.kvp_delete.key,
  351. HV_KVP_EXCHANGE_MAX_KEY_SIZE - 1) + 1;
  352. break;
  353. case KVP_OP_ENUMERATE:
  354. message->body.kvp_enum_data.index =
  355. in_msg->body.kvp_enum_data.index;
  356. break;
  357. }
  358. msg->len = sizeof(struct hv_kvp_msg);
  359. cn_netlink_send(msg, 0, GFP_ATOMIC);
  360. kfree(msg);
  361. return;
  362. }
  363. /*
  364. * Send a response back to the host.
  365. */
  366. static void
  367. kvp_respond_to_host(struct hv_kvp_msg *msg_to_host, int error)
  368. {
  369. struct hv_kvp_msg *kvp_msg;
  370. struct hv_kvp_exchg_msg_value *kvp_data;
  371. char *key_name;
  372. char *value;
  373. struct icmsg_hdr *icmsghdrp;
  374. int keylen = 0;
  375. int valuelen = 0;
  376. u32 buf_len;
  377. struct vmbus_channel *channel;
  378. u64 req_id;
  379. int ret;
  380. /*
  381. * If a transaction is not active; log and return.
  382. */
  383. if (!kvp_transaction.active) {
  384. /*
  385. * This is a spurious call!
  386. */
  387. pr_warn("KVP: Transaction not active\n");
  388. return;
  389. }
  390. /*
  391. * Copy the global state for completing the transaction. Note that
  392. * only one transaction can be active at a time.
  393. */
  394. buf_len = kvp_transaction.recv_len;
  395. channel = kvp_transaction.recv_channel;
  396. req_id = kvp_transaction.recv_req_id;
  397. kvp_transaction.active = false;
  398. icmsghdrp = (struct icmsg_hdr *)
  399. &recv_buffer[sizeof(struct vmbuspipe_hdr)];
  400. if (channel->onchannel_callback == NULL)
  401. /*
  402. * We have raced with util driver being unloaded;
  403. * silently return.
  404. */
  405. return;
  406. icmsghdrp->status = error;
  407. /*
  408. * If the error parameter is set, terminate the host's enumeration
  409. * on this pool.
  410. */
  411. if (error) {
  412. /*
  413. * Something failed or we have timedout;
  414. * terminate the current host-side iteration.
  415. */
  416. goto response_done;
  417. }
  418. kvp_msg = (struct hv_kvp_msg *)
  419. &recv_buffer[sizeof(struct vmbuspipe_hdr) +
  420. sizeof(struct icmsg_hdr)];
  421. switch (kvp_transaction.kvp_msg->kvp_hdr.operation) {
  422. case KVP_OP_GET_IP_INFO:
  423. ret = process_ob_ipinfo(msg_to_host,
  424. (struct hv_kvp_ip_msg *)kvp_msg,
  425. KVP_OP_GET_IP_INFO);
  426. if (ret < 0)
  427. icmsghdrp->status = HV_E_FAIL;
  428. goto response_done;
  429. case KVP_OP_SET_IP_INFO:
  430. goto response_done;
  431. case KVP_OP_GET:
  432. kvp_data = &kvp_msg->body.kvp_get.data;
  433. goto copy_value;
  434. case KVP_OP_SET:
  435. case KVP_OP_DELETE:
  436. goto response_done;
  437. default:
  438. break;
  439. }
  440. kvp_data = &kvp_msg->body.kvp_enum_data.data;
  441. key_name = msg_to_host->body.kvp_enum_data.data.key;
  442. /*
  443. * The windows host expects the key/value pair to be encoded
  444. * in utf16. Ensure that the key/value size reported to the host
  445. * will be less than or equal to the MAX size (including the
  446. * terminating character).
  447. */
  448. keylen = utf8s_to_utf16s(key_name, strlen(key_name), UTF16_HOST_ENDIAN,
  449. (wchar_t *) kvp_data->key,
  450. (HV_KVP_EXCHANGE_MAX_KEY_SIZE / 2) - 2);
  451. kvp_data->key_size = 2*(keylen + 1); /* utf16 encoding */
  452. copy_value:
  453. value = msg_to_host->body.kvp_enum_data.data.value;
  454. valuelen = utf8s_to_utf16s(value, strlen(value), UTF16_HOST_ENDIAN,
  455. (wchar_t *) kvp_data->value,
  456. (HV_KVP_EXCHANGE_MAX_VALUE_SIZE / 2) - 2);
  457. kvp_data->value_size = 2*(valuelen + 1); /* utf16 encoding */
  458. /*
  459. * If the utf8s to utf16s conversion failed; notify host
  460. * of the error.
  461. */
  462. if ((keylen < 0) || (valuelen < 0))
  463. icmsghdrp->status = HV_E_FAIL;
  464. kvp_data->value_type = REG_SZ; /* all our values are strings */
  465. response_done:
  466. icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE;
  467. vmbus_sendpacket(channel, recv_buffer, buf_len, req_id,
  468. VM_PKT_DATA_INBAND, 0);
  469. }
  470. /*
  471. * This callback is invoked when we get a KVP message from the host.
  472. * The host ensures that only one KVP transaction can be active at a time.
  473. * KVP implementation in Linux needs to forward the key to a user-mde
  474. * component to retrive the corresponding value. Consequently, we cannot
  475. * respond to the host in the conext of this callback. Since the host
  476. * guarantees that at most only one transaction can be active at a time,
  477. * we stash away the transaction state in a set of global variables.
  478. */
  479. void hv_kvp_onchannelcallback(void *context)
  480. {
  481. struct vmbus_channel *channel = context;
  482. u32 recvlen;
  483. u64 requestid;
  484. struct hv_kvp_msg *kvp_msg;
  485. struct icmsg_hdr *icmsghdrp;
  486. struct icmsg_negotiate *negop = NULL;
  487. if (kvp_transaction.active) {
  488. /*
  489. * We will defer processing this callback once
  490. * the current transaction is complete.
  491. */
  492. kvp_transaction.kvp_context = context;
  493. return;
  494. }
  495. vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 2, &recvlen,
  496. &requestid);
  497. if (recvlen > 0) {
  498. icmsghdrp = (struct icmsg_hdr *)&recv_buffer[
  499. sizeof(struct vmbuspipe_hdr)];
  500. if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
  501. vmbus_prep_negotiate_resp(icmsghdrp, negop,
  502. recv_buffer, MAX_SRV_VER, MAX_SRV_VER);
  503. } else {
  504. kvp_msg = (struct hv_kvp_msg *)&recv_buffer[
  505. sizeof(struct vmbuspipe_hdr) +
  506. sizeof(struct icmsg_hdr)];
  507. /*
  508. * Stash away this global state for completing the
  509. * transaction; note transactions are serialized.
  510. */
  511. kvp_transaction.recv_len = recvlen;
  512. kvp_transaction.recv_channel = channel;
  513. kvp_transaction.recv_req_id = requestid;
  514. kvp_transaction.active = true;
  515. kvp_transaction.kvp_msg = kvp_msg;
  516. /*
  517. * Get the information from the
  518. * user-mode component.
  519. * component. This transaction will be
  520. * completed when we get the value from
  521. * the user-mode component.
  522. * Set a timeout to deal with
  523. * user-mode not responding.
  524. */
  525. schedule_work(&kvp_sendkey_work);
  526. schedule_delayed_work(&kvp_work, 5*HZ);
  527. return;
  528. }
  529. icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
  530. | ICMSGHDRFLAG_RESPONSE;
  531. vmbus_sendpacket(channel, recv_buffer,
  532. recvlen, requestid,
  533. VM_PKT_DATA_INBAND, 0);
  534. }
  535. }
  536. int
  537. hv_kvp_init(struct hv_util_service *srv)
  538. {
  539. int err;
  540. err = cn_add_callback(&kvp_id, kvp_name, kvp_cn_callback);
  541. if (err)
  542. return err;
  543. recv_buffer = srv->recv_buffer;
  544. /*
  545. * When this driver loads, the user level daemon that
  546. * processes the host requests may not yet be running.
  547. * Defer processing channel callbacks until the daemon
  548. * has registered.
  549. */
  550. kvp_transaction.active = true;
  551. return 0;
  552. }
  553. void hv_kvp_deinit(void)
  554. {
  555. cn_del_callback(&kvp_id);
  556. cancel_delayed_work_sync(&kvp_work);
  557. cancel_work_sync(&kvp_sendkey_work);
  558. }