Hello community, here is the log from the commit of package hyper-v for openSUSE:Factory checked in at 2014-01-30 11:25:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/hyper-v (Old) and /work/SRC/openSUSE:Factory/.hyper-v.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "hyper-v" Changes: -------- --- /work/SRC/openSUSE:Factory/hyper-v/hyper-v.changes 2013-12-26 17:38:10.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.hyper-v.new/hyper-v.changes 2014-01-30 11:25:42.000000000 +0100 @@ -1,0 +2,13 @@ +Thu Jan 23 17:00:54 CET 2014 - [email protected] + +- Start daemons on demand via udev rules because the guest services + are optional. +- If systemd is used daemons live in libdir, they are not usercallable apps + +------------------------------------------------------------------- +Thu Jan 16 11:09:34 CET 2014 - [email protected] + +- Add hv_fcopy_daemon for post 13.1 releases (fate#315887) + hyper-v.tools.hv.hv_fcopy_daemon.c + +------------------------------------------------------------------- New: ---- hyper-v.tools.hv.hv_fcopy_daemon.c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ hyper-v.spec ++++++ --- /var/tmp/diff_new_pack.MgTr5e/_old 2014-01-30 11:25:44.000000000 +0100 +++ /var/tmp/diff_new_pack.MgTr5e/_new 2014-01-30 11:25:44.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package hyper-v # -# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,6 +18,7 @@ %define hv_kvp_daemon hv_kvp_daemon %define hv_vss_daemon hv_vss_daemon +%define hv_fcopy_daemon hv_fcopy_daemon %define helper_dir /usr/lib/%{name} Name: hyper-v @@ -50,6 +51,7 @@ Source11: hyper-v.init.sh Source12: hyper-v.tools.hv.hv_vss_daemon.c Source13: hyper-v.init.vss.sh +Source14: hyper-v.tools.hv.hv_fcopy_daemon.c Source20: hyper-v.tools.hv.hv_get_dhcp_info.sh Source21: hyper-v.tools.hv.hv_get_dns_info.sh Source22: hyper-v.tools.hv.hv_set_ifconfig.sh @@ -65,10 +67,12 @@ cp -vL %{S:9} %{hv_kvp_daemon}.h cp -vL %{S:10} %{hv_kvp_daemon}.c cp -vL %{S:12} %{hv_vss_daemon}.c +cp -vL %{S:14} %{hv_fcopy_daemon}.c %build sed -i~ '/#include <linux.hyperv.h>/d' %{hv_kvp_daemon}.c sed -i~ '/#include <linux.hyperv.h>/d' %{hv_vss_daemon}.c +sed -i~ '/#include <linux.hyperv.h>/d' %{hv_fcopy_daemon}.c gcc \ $RPM_OPT_FLAGS \ -Wno-unused-variable \ @@ -91,12 +95,28 @@ -DCN_VSS_IDX=0xa \ -DCN_VSS_VAL=0x1 \ -o %{hv_vss_daemon} +gcc \ + $RPM_OPT_FLAGS \ + -Wno-unused-variable \ + -Wno-pointer-sign \ + -D_GNU_SOURCE \ + -g \ + %{hv_fcopy_daemon}.c \ + -include %{hv_kvp_daemon}.h \ + -o %{hv_fcopy_daemon} %install -mkdir -p $RPM_BUILD_ROOT/usr/sbin -install -m755 %{hv_kvp_daemon} $RPM_BUILD_ROOT/usr/sbin -install -m755 %{hv_vss_daemon} $RPM_BUILD_ROOT/usr/sbin +%if %{use_systemd} +# It is not a callable app anyway, so move it out of the way +bindir=%{helper_dir}/bin +%else +bindir=/usr/sbin +%endif +mkdir -p $RPM_BUILD_ROOT${bindir} mkdir -p $RPM_BUILD_ROOT%{helper_dir}/bin +install -m755 %{hv_kvp_daemon} $RPM_BUILD_ROOT${bindir} +install -m755 %{hv_vss_daemon} $RPM_BUILD_ROOT${bindir} +install -m755 %{hv_fcopy_daemon} $RPM_BUILD_ROOT${bindir} cp -avL %{S:20} $RPM_BUILD_ROOT%{helper_dir}/bin/hv_get_dhcp_info cp -avL %{S:21} $RPM_BUILD_ROOT%{helper_dir}/bin/hv_get_dns_info cp -avL %{S:22} $RPM_BUILD_ROOT%{helper_dir}/bin/hv_set_ifconfig @@ -105,18 +125,19 @@ d=$RPM_BUILD_ROOT%{_unitdir} mkdir -vp ${d} # -cat > ${d}/%{hv_kvp_daemon}.service <<'EOF' +cat > ${d}/%{hv_kvp_daemon}.service <<EOF +# started via %{_udevrulesdir}/%{hv_kvp_daemon}.rules [Unit] Description=Hyper-V KVP Daemon ConditionVirtualization=microsoft [Service] -Environment=%{helper_dir}/bin:/usr/sbin:/usr/bin:/sbin:/bin +Environment="PATH=%{helper_dir}/bin:/usr/sbin:/usr/bin:/sbin:/bin" Type=forking # Restart appears to work, but its unsupported # Reboot required until kernel-user protocol is fixed ExecStartPre=/usr/bin/mkdir /run/%{hv_kvp_daemon} -ExecStart=/usr/sbin/%{hv_kvp_daemon} +ExecStart=${bindir}/%{hv_kvp_daemon} ExecReload=/usr/bin/false Restart=no @@ -124,7 +145,8 @@ WantedBy=default.target EOF # -cat > ${d}/%{hv_vss_daemon}.service <<'EOF' +cat > ${d}/%{hv_vss_daemon}.service <<EOF +# started via %{_udevrulesdir}/%{hv_vss_daemon}.rules [Unit] Description=Hyper-V VSS Daemon ConditionVirtualization=microsoft @@ -134,7 +156,7 @@ # Restart appears to work, but its unsupported # Reboot required until kernel-user protocol is fixed ExecStartPre=/usr/bin/mkdir /run/%{hv_vss_daemon} -ExecStart=/usr/sbin/%{hv_vss_daemon} +ExecStart=${bindir}/%{hv_vss_daemon} ExecReload=/usr/bin/false Restart=no @@ -142,13 +164,43 @@ WantedBy=default.target EOF # +cat > ${d}/%{hv_fcopy_daemon}.service <<EOF +# started via %{_udevrulesdir}/%{hv_fcopy_daemon}.rules +[Unit] +Description=Hyper-V host to guest file copy daemon +ConditionVirtualization=microsoft + +[Service] +Type=forking +ExecStart=${bindir}/%{hv_fcopy_daemon} + +[Install] +WantedBy=default.target +EOF +# head -n 42 ${d}/*.service +# +# +d=$RPM_BUILD_ROOT%{_udevrulesdir} +mkdir -vp ${d} +cat > ${d}/%{hv_kvp_daemon}.rules <<EOF +SUBSYSTEM=="vmbus", ACTION=="add", ATTR{class_id}=="{a9a0f4e7-5a45-4d96-b827-8a841e8c03e6}", TAG+="systemd", ENV{SYSTEMD_WANTS}+="%{hv_kvp_daemon}.service" +EOF +cat > ${d}/%{hv_vss_daemon}.rules <<EOF +SUBSYSTEM=="vmbus", ACTION=="add", ATTR{class_id}=="{35fa2e29-ea23-4236-96ae-3a6ebacba440}", TAG+="systemd", ENV{SYSTEMD_WANTS}+="%{hv_vss_daemon}.service" +EOF +cat > ${d}/%{hv_fcopy_daemon}.rules <<EOF +ACTION=="add", KERNEL=="hv_fcopy", TAG+="systemd", ENV{SYSTEMD_WANTS}+="%{hv_fcopy_daemon}.service" +EOF +# +head -n 42 ${d}/*.rules +# %else mkdir -p $RPM_BUILD_ROOT/etc/init.d install -m755 %{S:11} $RPM_BUILD_ROOT/etc/init.d/%{hv_kvp_daemon} -ln -sfvbn ../../etc/init.d/%{hv_kvp_daemon} $RPM_BUILD_ROOT/usr/sbin/rc%{hv_kvp_daemon} +ln -sfvbn ../../etc/init.d/%{hv_kvp_daemon} $RPM_BUILD_ROOT${bindir}/rc%{hv_kvp_daemon} install -m755 %{S:13} $RPM_BUILD_ROOT/etc/init.d/%{hv_vss_daemon} -ln -sfvbn ../../etc/init.d/%{hv_vss_daemon} $RPM_BUILD_ROOT/usr/sbin/rc%{hv_vss_daemon} +ln -sfvbn ../../etc/init.d/%{hv_vss_daemon} $RPM_BUILD_ROOT${bindir}/rc%{hv_vss_daemon} %endif %files @@ -156,10 +208,11 @@ %doc kvptest.ps1.txt %if %{use_systemd} %{_unitdir} +%{_udevrulesdir} %else /etc/init.d/* -%endif /usr/sbin/* +%endif %{helper_dir} %pre @@ -181,8 +234,7 @@ rmdir -v /var/opt/hyperv || : fi %if %{use_systemd} -%{service_add_pre %{hv_kvp_daemon}.service} -%{service_add_pre %{hv_vss_daemon}.service} +: nothing to do in case of systemd %endif %post @@ -203,8 +255,7 @@ if test "${board_vendor}" = "Microsoft Corporation" -a "${product_name}" = "Virtual Machine" then %if %{use_systemd} -%{service_add_post %{hv_kvp_daemon}.service} -%{service_add_post %{hv_vss_daemon}.service} +: nothing to do in case of systemd %else echo "Enabling %{hv_kvp_daemon} on '${product_name}' from '${board_vendor}'" %{insserv_force_if_yast %{hv_kvp_daemon}} @@ -215,8 +266,7 @@ %preun %if %{use_systemd} -%{service_del_preun %{hv_kvp_daemon}.service} -%{service_del_preun %{hv_vss_daemon}.service} +: nothing to do in case of systemd %else %stop_on_removal %{hv_kvp_daemon} %stop_on_removal %{hv_vss_daemon} @@ -225,8 +275,7 @@ %postun # no restart on update because the daemon can not be restarted %if %{use_systemd} -%{service_del_postun %{hv_kvp_daemon}.service} -%{service_del_postun %{hv_vss_daemon}.service} +: nothing to do in case of systemd %else %insserv_cleanup %endif ++++++ hyper-v.include.linux.hyperv.h ++++++ --- /var/tmp/diff_new_pack.MgTr5e/_old 2014-01-30 11:25:44.000000000 +0100 +++ /var/tmp/diff_new_pack.MgTr5e/_new 2014-01-30 11:25:44.000000000 +0100 @@ -26,6 +26,10 @@ #define _HYPERV_H #include <linux/types.h> +/* from linux/uuid.h */ +typedef struct { + __u8 b[16]; +} uuid_le; /* @@ -84,6 +88,52 @@ }; } __attribute__((packed)); + +/* + * Implementation of a host to guest copy facility. + */ + +#define FCOPY_VERSION_0 0 +#define FCOPY_CURRENT_VERSION FCOPY_VERSION_0 +#define W_MAX_PATH 260 + +enum hv_fcopy_op { + START_FILE_COPY = 0, + WRITE_TO_FILE, + COMPLETE_FCOPY, + CANCEL_FCOPY, +}; + +struct hv_fcopy_hdr { + __u32 operation; + uuid_le service_id0; /* currently unused */ + uuid_le service_id1; /* currently unused */ +} __attribute__((packed)); + +#define OVER_WRITE 0x1 +#define CREATE_PATH 0x2 + +struct hv_start_fcopy { + struct hv_fcopy_hdr hdr; + __u16 file_name[W_MAX_PATH]; + __u16 path_name[W_MAX_PATH]; + __u32 copy_flags; + __u64 file_size; +} __attribute__((packed)); + +/* + * The file is chunked into fragments. + */ +#define DATA_FRAGMENT (6 * 1024) + +struct hv_do_fcopy { + struct hv_fcopy_hdr hdr; + __u64 offset; + __u32 size; + __u8 data[DATA_FRAGMENT]; +}; + + /* * An implementation of HyperV key value pair (KVP) functionality for Linux. * ++++++ hyper-v.tools.hv.hv_fcopy_daemon.c ++++++ /* * An implementation of host to guest copy functionality for Linux. * * Copyright (C) 2014, Microsoft, Inc. * * Author : K. Y. Srinivasan <[email protected]> * * 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 = 0; 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/hv_fcopy", O_RDWR); if (fcopy_fd < 0) { syslog(LOG_ERR, "open /dev/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) { if (!error) { syslog(LOG_ERR, "Read error: %s", strerror(errno)); error = HV_E_FAIL; } continue; } 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); } } } -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
