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]

Reply via email to