summary refs log tree commit diff
path: root/tools
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-01 16:13:21 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-01 16:13:21 -0700
commit675c354a95d5375153b8bb80a0448cab916c7991 (patch)
tree88cbc5a5a31dd1c1016271006a8d56cfe0abf7bd /tools
parentc70929147a10fa4538886cb23b934b509c4c0e49 (diff)
parent1b3fa22e0234d613df967445cd34807e10fa54fa (diff)
downloadlinux-675c354a95d5375153b8bb80a0448cab916c7991.tar.gz
Merge tag 'char-misc-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver patches from Greg KH:
 "Here's the big char/misc driver updates for 3.15-rc1.

  Lots of various things here, including the new mcb driver subsystem.

  All of these have been in linux-next for a while"

* tag 'char-misc-3.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (118 commits)
  extcon: Move OF helper function to extcon core and change function name
  extcon: of: Remove unnecessary function call by using the name of device_node
  extcon: gpio: Use SIMPLE_DEV_PM_OPS macro
  extcon: palmas: Use SIMPLE_DEV_PM_OPS macro
  mei: don't use deprecated DEFINE_PCI_DEVICE_TABLE macro
  mei: amthif: fix checkpatch error
  mei: client.h fix checkpatch errors
  mei: use cl_dbg where appropriate
  mei: fix Unnecessary space after function pointer name
  mei: report consistently copy_from/to_user failures
  mei: drop pr_fmt macros
  mei: make me hw headers private to me hw.
  mei: fix memory leak of pending write cb objects
  mei: me: do not reset when less than expected data is received
  drivers: mcb: Fix build error discovered by 0-day bot
  cs5535-mfgpt: Simplify dependencies
  spmi: pm: drop bus-level PM suspend/resume routines
  spmi: pmic_arb: make selectable on ARCH_QCOM
  Drivers: hv: vmbus: Increase the limit on the number of pfns we can handle
  pch_phub: Report error writing MAC back to user
  ...
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile11
-rw-r--r--tools/hv/Makefile13
-rw-r--r--tools/hv/hv_fcopy_daemon.c195
-rw-r--r--tools/hv/hv_vss_daemon.c2
4 files changed, 216 insertions, 5 deletions
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
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 <kys@microsoft.com>
+ *
+ * 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 <sys/types.h>
+#include <sys/socket.h>
+#include <sys/poll.h>
+#include <linux/types.h>
+#include <linux/kdev_t.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <linux/hyperv.h>
+#include <syslog.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+
+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);
+		}
+	}
+}
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;