From 3eb2094c59e89db2bedd401e23c7a870081c9edb Mon Sep 17 00:00:00 2001 From: Bjarke Istrup Pedersen Date: Sun, 9 Feb 2014 11:41:52 +0000 Subject: Adding makefile for tools/hv Currently, there is no makefile for the Hyper-V tools. This patch adds the missing makefile, and adds it to the main tools makefile. Signed-off-by: Bjarke Istrup Pedersen Signed-off-by: Greg Kroah-Hartman --- tools/Makefile | 11 ++++++----- tools/hv/Makefile | 13 +++++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 tools/hv/Makefile (limited to 'tools') diff --git a/tools/Makefile b/tools/Makefile index feec3ad5fd09..bcae806b0c39 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -7,6 +7,7 @@ help: @echo ' cgroup - cgroup tools' @echo ' cpupower - a tool for all things x86 CPU power' @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer' + @echo ' hv - tools used when in Hyper-V clients' @echo ' lguest - a minimal 32-bit x86 hypervisor' @echo ' perf - Linux performance measurement and analysis tool' @echo ' selftests - various kernel selftests' @@ -40,7 +41,7 @@ acpi: FORCE cpupower: FORCE $(call descend,power/$@) -cgroup firewire guest usb virtio vm net: FORCE +cgroup firewire hv guest usb virtio vm net: FORCE $(call descend,$@) libapikfs: FORCE @@ -64,7 +65,7 @@ acpi_install: cpupower_install: $(call descend,power/$(@:_install=),install) -cgroup_install firewire_install lguest_install perf_install usb_install virtio_install vm_install net_install: +cgroup_install firewire_install hv_install lguest_install perf_install usb_install virtio_install vm_install net_install: $(call descend,$(@:_install=),install) selftests_install: @@ -76,7 +77,7 @@ turbostat_install x86_energy_perf_policy_install: tmon_install: $(call descend,thermal/$(@:_install=),install) -install: acpi_install cgroup_install cpupower_install firewire_install lguest_install \ +install: acpi_install cgroup_install cpupower_install hv_install firewire_install lguest_install \ perf_install selftests_install turbostat_install usb_install \ virtio_install vm_install net_install x86_energy_perf_policy_install \ tmon @@ -87,7 +88,7 @@ acpi_clean: cpupower_clean: $(call descend,power/cpupower,clean) -cgroup_clean firewire_clean lguest_clean usb_clean virtio_clean vm_clean net_clean: +cgroup_clean hv_clean firewire_clean lguest_clean usb_clean virtio_clean vm_clean net_clean: $(call descend,$(@:_clean=),clean) libapikfs_clean: @@ -105,7 +106,7 @@ turbostat_clean x86_energy_perf_policy_clean: tmon_clean: $(call descend,thermal/tmon,clean) -clean: acpi_clean cgroup_clean cpupower_clean firewire_clean lguest_clean \ +clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean lguest_clean \ perf_clean selftests_clean turbostat_clean usb_clean virtio_clean \ vm_clean net_clean x86_energy_perf_policy_clean tmon_clean diff --git a/tools/hv/Makefile b/tools/hv/Makefile new file mode 100644 index 000000000000..bd22f786a60c --- /dev/null +++ b/tools/hv/Makefile @@ -0,0 +1,13 @@ +# Makefile for Hyper-V tools + +CC = $(CROSS_COMPILE)gcc +PTHREAD_LIBS = -lpthread +WARNINGS = -Wall -Wextra +CFLAGS = $(WARNINGS) -g $(PTHREAD_LIBS) + +all: hv_kvp_daemon hv_vss_daemon +%: %.c + $(CC) $(CFLAGS) -o $@ $^ + +clean: + $(RM) hv_kvp_daemon hv_vss_daemon -- cgit v1.2.3 From f33b215549938f89aebf862b942366d2aa41c191 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 12 Feb 2014 08:40:22 -0800 Subject: Tools: hv: vssdaemon: Ignore VFAT mounts during the Freeze operation If the guest has a FAT file system mounted, skip it during the FREEZE operation. With this change we can support host initiated backup of the guest even when the guest may have FAT file systems mounted. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- tools/hv/hv_vss_daemon.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c index 520de3304571..6a213b8cd7b9 100644 --- a/tools/hv/hv_vss_daemon.c +++ b/tools/hv/hv_vss_daemon.c @@ -87,6 +87,8 @@ static int vss_operate(int operation) continue; if (strcmp(ent->mnt_type, "iso9660") == 0) continue; + if (strcmp(ent->mnt_type, "vfat") == 0) + continue; if (strcmp(ent->mnt_dir, "/") == 0) { root_seen = 1; continue; -- cgit v1.2.3 From 01325476d6e46185031be4a9bc6443832dbc807c Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Sun, 16 Feb 2014 11:34:30 -0800 Subject: Drivers: hv: Implement the file copy service Implement the file copy service for Linux guests on Hyper-V. This permits the host to copy a file (over VMBUS) into the guest. This facility is part of "guest integration services" supported on the Windows platform. Here is a link that provides additional details on this functionality: http://technet.microsoft.com/en-us/library/dn464282.aspx In V1 version of the patch I have addressed comments from Olaf Hering and Dan Carpenter In V2 version of this patch I did some minor cleanup (making some globals static). In V4 version of the patch I have addressed all of Olaf's most recent set of comments/concerns. In V5 version of the patch I had addressed Greg's most recent comments. I would like to thank Greg for suggesting that I use misc device; it has significantly simplified the code. In V6 version of the patch I have cleaned up error message based on Olaf's comments. I have also rebased the patch based on the current tip. In this version of the patch, I have addressed the latest comments from Greg. Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman --- tools/hv/hv_fcopy_daemon.c | 195 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 tools/hv/hv_fcopy_daemon.c (limited to 'tools') diff --git a/tools/hv/hv_fcopy_daemon.c b/tools/hv/hv_fcopy_daemon.c new file mode 100644 index 000000000000..4ecc4fd0bc1b --- /dev/null +++ b/tools/hv/hv_fcopy_daemon.c @@ -0,0 +1,195 @@ +/* + * An implementation of host to guest copy functionality for Linux. + * + * Copyright (C) 2014, Microsoft, Inc. + * + * Author : K. Y. Srinivasan + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int target_fd; +static char target_fname[W_MAX_PATH]; + +static int hv_start_fcopy(struct hv_start_fcopy *smsg) +{ + int error = HV_E_FAIL; + char *q, *p; + + /* + * If possile append a path seperator to the path. + */ + if (strlen((char *)smsg->path_name) < (W_MAX_PATH - 2)) + strcat((char *)smsg->path_name, "/"); + + p = (char *)smsg->path_name; + snprintf(target_fname, sizeof(target_fname), "%s/%s", + (char *)smsg->path_name, smsg->file_name); + + syslog(LOG_INFO, "Target file name: %s", target_fname); + /* + * Check to see if the path is already in place; if not, + * create if required. + */ + while ((q = strchr(p, '/')) != NULL) { + if (q == p) { + p++; + continue; + } + *q = '\0'; + if (access((char *)smsg->path_name, F_OK)) { + if (smsg->copy_flags & CREATE_PATH) { + if (mkdir((char *)smsg->path_name, 0755)) { + syslog(LOG_ERR, "Failed to create %s", + (char *)smsg->path_name); + goto done; + } + } else { + syslog(LOG_ERR, "Invalid path: %s", + (char *)smsg->path_name); + goto done; + } + } + p = q + 1; + *q = '/'; + } + + if (!access(target_fname, F_OK)) { + syslog(LOG_INFO, "File: %s exists", target_fname); + if (!smsg->copy_flags & OVER_WRITE) + goto done; + } + + target_fd = open(target_fname, O_RDWR | O_CREAT | O_CLOEXEC, 0744); + if (target_fd == -1) { + syslog(LOG_INFO, "Open Failed: %s", strerror(errno)); + goto done; + } + + error = 0; +done: + return error; +} + +static int hv_copy_data(struct hv_do_fcopy *cpmsg) +{ + ssize_t bytes_written; + + bytes_written = pwrite(target_fd, cpmsg->data, cpmsg->size, + cpmsg->offset); + + if (bytes_written != cpmsg->size) + return HV_E_FAIL; + + return 0; +} + +static int hv_copy_finished(void) +{ + close(target_fd); + return 0; +} +static int hv_copy_cancel(void) +{ + close(target_fd); + unlink(target_fname); + return 0; + +} + +int main(void) +{ + int fd, fcopy_fd, len; + int error; + int version = FCOPY_CURRENT_VERSION; + char *buffer[4096 * 2]; + struct hv_fcopy_hdr *in_msg; + + if (daemon(1, 0)) { + syslog(LOG_ERR, "daemon() failed; error: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + + openlog("HV_FCOPY", 0, LOG_USER); + syslog(LOG_INFO, "HV_FCOPY starting; pid is:%d", getpid()); + + fcopy_fd = open("/dev/vmbus/hv_fcopy", O_RDWR); + + if (fcopy_fd < 0) { + syslog(LOG_ERR, "open /dev/vmbus/hv_fcopy failed; error: %d %s", + errno, strerror(errno)); + exit(EXIT_FAILURE); + } + + /* + * Register with the kernel. + */ + if ((write(fcopy_fd, &version, sizeof(int))) != sizeof(int)) { + syslog(LOG_ERR, "Registration failed: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + + while (1) { + /* + * In this loop we process fcopy messages after the + * handshake is complete. + */ + len = pread(fcopy_fd, buffer, (4096 * 2), 0); + if (len < 0) { + syslog(LOG_ERR, "pread failed: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + in_msg = (struct hv_fcopy_hdr *)buffer; + + switch (in_msg->operation) { + case START_FILE_COPY: + error = hv_start_fcopy((struct hv_start_fcopy *)in_msg); + break; + case WRITE_TO_FILE: + error = hv_copy_data((struct hv_do_fcopy *)in_msg); + break; + case COMPLETE_FCOPY: + error = hv_copy_finished(); + break; + case CANCEL_FCOPY: + error = hv_copy_cancel(); + break; + + default: + syslog(LOG_ERR, "Unknown operation: %d", + in_msg->operation); + + } + + if (pwrite(fcopy_fd, &error, sizeof(int), 0) != sizeof(int)) { + syslog(LOG_ERR, "pwrite failed: %s", strerror(errno)); + exit(EXIT_FAILURE); + } + } +} -- cgit v1.2.3