1 /* 2 * An implementation of host initiated guest snapshot. 3 * 4 * 5 * Copyright (C) 2013, Microsoft, Inc. 6 * Author : K. Y. Srinivasan <kys@microsoft.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 */ 19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 20 21 #include <linux/net.h> 22 #include <linux/nls.h> 23 #include <linux/connector.h> 24 #include <linux/workqueue.h> 25 #include <linux/hyperv.h> 26 27 28 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 38 static struct { 39 bool active; /* transaction status - active or not */ 40 int recv_len; /* number of bytes received. */ 41 struct vmbus_channel *recv_channel; /* chn we got the request */ 42 u64 recv_req_id; /* request ID. */ 43 struct hv_vss_msg *msg; /* current message */ 44 } vss_transaction; 45 46 47 static void vss_respond_to_host(int error); 48 49 static struct cb_id vss_id = { CN_VSS_IDX, CN_VSS_VAL }; 50 static const char vss_name[] = "vss_kernel_module"; 51 static __u8 *recv_buffer; 52 53 static void vss_send_op(struct work_struct *dummy); 54 static DECLARE_WORK(vss_send_op_work, vss_send_op); 55 56 /* 57 * Callback when data is received from user mode. 58 */ 59 60 static void 61 vss_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) 62 { 63 struct hv_vss_msg *vss_msg; 64 65 vss_msg = (struct hv_vss_msg *)msg->data; 66 67 if (vss_msg->vss_hdr.operation == VSS_OP_REGISTER) { 68 pr_info("VSS daemon registered\n"); 69 vss_transaction.active = false; 70 if (vss_transaction.recv_channel != NULL) 71 hv_vss_onchannelcallback(vss_transaction.recv_channel); 72 return; 73 74 } 75 vss_respond_to_host(vss_msg->error); 76 } 77 78 79 static void vss_send_op(struct work_struct *dummy) 80 { 81 int op = vss_transaction.msg->vss_hdr.operation; 82 struct cn_msg *msg; 83 struct hv_vss_msg *vss_msg; 84 85 msg = kzalloc(sizeof(*msg) + sizeof(*vss_msg), GFP_ATOMIC); 86 if (!msg) 87 return; 88 89 vss_msg = (struct hv_vss_msg *)msg->data; 90 91 msg->id.idx = CN_VSS_IDX; 92 msg->id.val = CN_VSS_VAL; 93 94 vss_msg->vss_hdr.operation = op; 95 msg->len = sizeof(struct hv_vss_msg); 96 97 cn_netlink_send(msg, 0, GFP_ATOMIC); 98 kfree(msg); 99 100 return; 101 } 102 103 /* 104 * Send a response back to the host. 105 */ 106 107 static void 108 vss_respond_to_host(int error) 109 { 110 struct icmsg_hdr *icmsghdrp; 111 u32 buf_len; 112 struct vmbus_channel *channel; 113 u64 req_id; 114 115 /* 116 * If a transaction is not active; log and return. 117 */ 118 119 if (!vss_transaction.active) { 120 /* 121 * This is a spurious call! 122 */ 123 pr_warn("VSS: Transaction not active\n"); 124 return; 125 } 126 /* 127 * Copy the global state for completing the transaction. Note that 128 * only one transaction can be active at a time. 129 */ 130 131 buf_len = vss_transaction.recv_len; 132 channel = vss_transaction.recv_channel; 133 req_id = vss_transaction.recv_req_id; 134 vss_transaction.active = false; 135 136 icmsghdrp = (struct icmsg_hdr *) 137 &recv_buffer[sizeof(struct vmbuspipe_hdr)]; 138 139 if (channel->onchannel_callback == NULL) 140 /* 141 * We have raced with util driver being unloaded; 142 * silently return. 143 */ 144 return; 145 146 icmsghdrp->status = error; 147 148 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; 149 150 vmbus_sendpacket(channel, recv_buffer, buf_len, req_id, 151 VM_PKT_DATA_INBAND, 0); 152 153 } 154 155 /* 156 * This callback is invoked when we get a VSS message from the host. 157 * The host ensures that only one VSS transaction can be active at a time. 158 */ 159 160 void hv_vss_onchannelcallback(void *context) 161 { 162 struct vmbus_channel *channel = context; 163 u32 recvlen; 164 u64 requestid; 165 struct hv_vss_msg *vss_msg; 166 167 168 struct icmsg_hdr *icmsghdrp; 169 struct icmsg_negotiate *negop = NULL; 170 171 if (vss_transaction.active) { 172 /* 173 * We will defer processing this callback once 174 * the current transaction is complete. 175 */ 176 vss_transaction.recv_channel = channel; 177 return; 178 } 179 180 vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 2, &recvlen, 181 &requestid); 182 183 if (recvlen > 0) { 184 icmsghdrp = (struct icmsg_hdr *)&recv_buffer[ 185 sizeof(struct vmbuspipe_hdr)]; 186 187 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { 188 vmbus_prep_negotiate_resp(icmsghdrp, negop, 189 recv_buffer, MAX_SRV_VER, MAX_SRV_VER); 190 /* 191 * We currently negotiate the highest number the 192 * host has presented. If this version is not 193 * atleast 5.0, reject. 194 */ 195 negop = (struct icmsg_negotiate *)&recv_buffer[ 196 sizeof(struct vmbuspipe_hdr) + 197 sizeof(struct icmsg_hdr)]; 198 199 if (negop->icversion_data[1].major < 5) 200 negop->icframe_vercnt = 0; 201 } else { 202 vss_msg = (struct hv_vss_msg *)&recv_buffer[ 203 sizeof(struct vmbuspipe_hdr) + 204 sizeof(struct icmsg_hdr)]; 205 206 /* 207 * Stash away this global state for completing the 208 * transaction; note transactions are serialized. 209 */ 210 211 vss_transaction.recv_len = recvlen; 212 vss_transaction.recv_channel = channel; 213 vss_transaction.recv_req_id = requestid; 214 vss_transaction.active = true; 215 vss_transaction.msg = (struct hv_vss_msg *)vss_msg; 216 217 switch (vss_msg->vss_hdr.operation) { 218 /* 219 * Initiate a "freeze/thaw" 220 * operation in the guest. 221 * We respond to the host once 222 * the operation is complete. 223 * 224 * We send the message to the 225 * user space daemon and the 226 * operation is performed in 227 * the daemon. 228 */ 229 case VSS_OP_FREEZE: 230 case VSS_OP_THAW: 231 schedule_work(&vss_send_op_work); 232 return; 233 234 case VSS_OP_HOT_BACKUP: 235 vss_msg->vss_cf.flags = 236 VSS_HBU_NO_AUTO_RECOVERY; 237 vss_respond_to_host(0); 238 return; 239 240 case VSS_OP_GET_DM_INFO: 241 vss_msg->dm_info.flags = 0; 242 vss_respond_to_host(0); 243 return; 244 245 default: 246 vss_respond_to_host(0); 247 return; 248 249 } 250 251 } 252 253 icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION 254 | ICMSGHDRFLAG_RESPONSE; 255 256 vmbus_sendpacket(channel, recv_buffer, 257 recvlen, requestid, 258 VM_PKT_DATA_INBAND, 0); 259 } 260 261 } 262 263 int 264 hv_vss_init(struct hv_util_service *srv) 265 { 266 int err; 267 268 err = cn_add_callback(&vss_id, vss_name, vss_cn_callback); 269 if (err) 270 return err; 271 recv_buffer = srv->recv_buffer; 272 273 /* 274 * When this driver loads, the user level daemon that 275 * processes the host requests may not yet be running. 276 * Defer processing channel callbacks until the daemon 277 * has registered. 278 */ 279 vss_transaction.active = true; 280 return 0; 281 } 282 283 void hv_vss_deinit(void) 284 { 285 cn_del_callback(&vss_id); 286 cancel_work_sync(&vss_send_op_work); 287 } 288