- 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 - Add hv_fcopy_daemon for post 13.1 releases (fate#315887) OBS-URL: https://build.opensuse.org/package/show/Virtualization/hyper-v?expand=0&rev=82
This commit is contained in:
parent
c462528d4c
commit
2273a54793
@ -1,3 +1,15 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Jan 23 17:00:54 CET 2014 - ohering@suse.de
|
||||||
|
|
||||||
|
- 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 - ohering@suse.de
|
||||||
|
|
||||||
|
- Add hv_fcopy_daemon for post 13.1 releases (fate#315887)
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Wed Dec 18 14:46:37 CET 2013 - ohering@suse.de
|
Wed Dec 18 14:46:37 CET 2013 - ohering@suse.de
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#define _HYPERV_H
|
#define _HYPERV_H
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <linux/uuid.h>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -84,6 +85,52 @@ struct hv_vss_msg {
|
|||||||
};
|
};
|
||||||
} __attribute__((packed));
|
} __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.
|
* An implementation of HyperV key value pair (KVP) functionality for Linux.
|
||||||
*
|
*
|
||||||
|
89
hyper-v.spec
89
hyper-v.spec
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# spec file for package hyper-v
|
# 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
|
# All modifications and additions to the file contributed by third parties
|
||||||
# remain the property of their copyright owners, unless otherwise agreed
|
# remain the property of their copyright owners, unless otherwise agreed
|
||||||
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
%define hv_kvp_daemon hv_kvp_daemon
|
%define hv_kvp_daemon hv_kvp_daemon
|
||||||
%define hv_vss_daemon hv_vss_daemon
|
%define hv_vss_daemon hv_vss_daemon
|
||||||
|
%define hv_fcopy_daemon hv_fcopy_daemon
|
||||||
%define helper_dir /usr/lib/%{name}
|
%define helper_dir /usr/lib/%{name}
|
||||||
|
|
||||||
Name: hyper-v
|
Name: hyper-v
|
||||||
@ -50,6 +51,7 @@ Source10: hyper-v.tools.hv.hv_kvp_daemon.c
|
|||||||
Source11: hyper-v.init.sh
|
Source11: hyper-v.init.sh
|
||||||
Source12: hyper-v.tools.hv.hv_vss_daemon.c
|
Source12: hyper-v.tools.hv.hv_vss_daemon.c
|
||||||
Source13: hyper-v.init.vss.sh
|
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
|
Source20: hyper-v.tools.hv.hv_get_dhcp_info.sh
|
||||||
Source21: hyper-v.tools.hv.hv_get_dns_info.sh
|
Source21: hyper-v.tools.hv.hv_get_dns_info.sh
|
||||||
Source22: hyper-v.tools.hv.hv_set_ifconfig.sh
|
Source22: hyper-v.tools.hv.hv_set_ifconfig.sh
|
||||||
@ -65,10 +67,12 @@ cp -avL %{S:5} kvptest.ps1.txt
|
|||||||
cp -vL %{S:9} %{hv_kvp_daemon}.h
|
cp -vL %{S:9} %{hv_kvp_daemon}.h
|
||||||
cp -vL %{S:10} %{hv_kvp_daemon}.c
|
cp -vL %{S:10} %{hv_kvp_daemon}.c
|
||||||
cp -vL %{S:12} %{hv_vss_daemon}.c
|
cp -vL %{S:12} %{hv_vss_daemon}.c
|
||||||
|
cp -vL %{S:14} %{hv_fcopy_daemon}.c
|
||||||
|
|
||||||
%build
|
%build
|
||||||
sed -i~ '/#include <linux.hyperv.h>/d' %{hv_kvp_daemon}.c
|
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_vss_daemon}.c
|
||||||
|
sed -i~ '/#include <linux.hyperv.h>/d' %{hv_fcopy_daemon}.c
|
||||||
gcc \
|
gcc \
|
||||||
$RPM_OPT_FLAGS \
|
$RPM_OPT_FLAGS \
|
||||||
-Wno-unused-variable \
|
-Wno-unused-variable \
|
||||||
@ -91,12 +95,28 @@ gcc \
|
|||||||
-DCN_VSS_IDX=0xa \
|
-DCN_VSS_IDX=0xa \
|
||||||
-DCN_VSS_VAL=0x1 \
|
-DCN_VSS_VAL=0x1 \
|
||||||
-o %{hv_vss_daemon}
|
-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
|
%install
|
||||||
mkdir -p $RPM_BUILD_ROOT/usr/sbin
|
%if %{use_systemd}
|
||||||
install -m755 %{hv_kvp_daemon} $RPM_BUILD_ROOT/usr/sbin
|
# It is not a callable app anyway, so move it out of the way
|
||||||
install -m755 %{hv_vss_daemon} $RPM_BUILD_ROOT/usr/sbin
|
bindir=%{helper_dir}/bin
|
||||||
|
%else
|
||||||
|
bindir=/usr/sbin
|
||||||
|
%endif
|
||||||
|
mkdir -p $RPM_BUILD_ROOT${bindir}
|
||||||
mkdir -p $RPM_BUILD_ROOT%{helper_dir}/bin
|
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: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:21} $RPM_BUILD_ROOT%{helper_dir}/bin/hv_get_dns_info
|
||||||
cp -avL %{S:22} $RPM_BUILD_ROOT%{helper_dir}/bin/hv_set_ifconfig
|
cp -avL %{S:22} $RPM_BUILD_ROOT%{helper_dir}/bin/hv_set_ifconfig
|
||||||
@ -105,18 +125,19 @@ chmod 755 $RPM_BUILD_ROOT%{helper_dir}/bin/*
|
|||||||
d=$RPM_BUILD_ROOT%{_unitdir}
|
d=$RPM_BUILD_ROOT%{_unitdir}
|
||||||
mkdir -vp ${d}
|
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]
|
[Unit]
|
||||||
Description=Hyper-V KVP Daemon
|
Description=Hyper-V KVP Daemon
|
||||||
ConditionVirtualization=microsoft
|
ConditionVirtualization=microsoft
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Environment=%{helper_dir}/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
Environment="PATH=%{helper_dir}/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
Type=forking
|
Type=forking
|
||||||
# Restart appears to work, but its unsupported
|
# Restart appears to work, but its unsupported
|
||||||
# Reboot required until kernel-user protocol is fixed
|
# Reboot required until kernel-user protocol is fixed
|
||||||
ExecStartPre=/usr/bin/mkdir /run/%{hv_kvp_daemon}
|
ExecStartPre=/usr/bin/mkdir /run/%{hv_kvp_daemon}
|
||||||
ExecStart=/usr/sbin/%{hv_kvp_daemon}
|
ExecStart=${bindir}/%{hv_kvp_daemon}
|
||||||
ExecReload=/usr/bin/false
|
ExecReload=/usr/bin/false
|
||||||
Restart=no
|
Restart=no
|
||||||
|
|
||||||
@ -124,7 +145,8 @@ Restart=no
|
|||||||
WantedBy=default.target
|
WantedBy=default.target
|
||||||
EOF
|
EOF
|
||||||
#
|
#
|
||||||
cat > ${d}/%{hv_vss_daemon}.service <<'EOF'
|
cat > ${d}/%{hv_vss_daemon}.service <<EOF
|
||||||
|
# started via %{_udevrulesdir}/%{hv_vss_daemon}.rules
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Hyper-V VSS Daemon
|
Description=Hyper-V VSS Daemon
|
||||||
ConditionVirtualization=microsoft
|
ConditionVirtualization=microsoft
|
||||||
@ -134,21 +156,51 @@ Type=forking
|
|||||||
# Restart appears to work, but its unsupported
|
# Restart appears to work, but its unsupported
|
||||||
# Reboot required until kernel-user protocol is fixed
|
# Reboot required until kernel-user protocol is fixed
|
||||||
ExecStartPre=/usr/bin/mkdir /run/%{hv_vss_daemon}
|
ExecStartPre=/usr/bin/mkdir /run/%{hv_vss_daemon}
|
||||||
ExecStart=/usr/sbin/%{hv_vss_daemon}
|
ExecStart=${bindir}/%{hv_vss_daemon}
|
||||||
ExecReload=/usr/bin/false
|
ExecReload=/usr/bin/false
|
||||||
Restart=no
|
Restart=no
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
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]
|
[Install]
|
||||||
WantedBy=default.target
|
WantedBy=default.target
|
||||||
EOF
|
EOF
|
||||||
#
|
#
|
||||||
head -n 42 ${d}/*.service
|
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
|
%else
|
||||||
mkdir -p $RPM_BUILD_ROOT/etc/init.d
|
mkdir -p $RPM_BUILD_ROOT/etc/init.d
|
||||||
install -m755 %{S:11} $RPM_BUILD_ROOT/etc/init.d/%{hv_kvp_daemon}
|
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}
|
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
|
%endif
|
||||||
|
|
||||||
%files
|
%files
|
||||||
@ -156,10 +208,11 @@ ln -sfvbn ../../etc/init.d/%{hv_vss_daemon} $RPM_BUILD_ROOT/usr/sbin/rc%{hv_vss_
|
|||||||
%doc kvptest.ps1.txt
|
%doc kvptest.ps1.txt
|
||||||
%if %{use_systemd}
|
%if %{use_systemd}
|
||||||
%{_unitdir}
|
%{_unitdir}
|
||||||
|
%{_udevrulesdir}
|
||||||
%else
|
%else
|
||||||
/etc/init.d/*
|
/etc/init.d/*
|
||||||
%endif
|
|
||||||
/usr/sbin/*
|
/usr/sbin/*
|
||||||
|
%endif
|
||||||
%{helper_dir}
|
%{helper_dir}
|
||||||
|
|
||||||
%pre
|
%pre
|
||||||
@ -181,8 +234,7 @@ then
|
|||||||
rmdir -v /var/opt/hyperv || :
|
rmdir -v /var/opt/hyperv || :
|
||||||
fi
|
fi
|
||||||
%if %{use_systemd}
|
%if %{use_systemd}
|
||||||
%{service_add_pre %{hv_kvp_daemon}.service}
|
: nothing to do in case of systemd
|
||||||
%{service_add_pre %{hv_vss_daemon}.service}
|
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%post
|
%post
|
||||||
@ -203,8 +255,7 @@ fi
|
|||||||
if test "${board_vendor}" = "Microsoft Corporation" -a "${product_name}" = "Virtual Machine"
|
if test "${board_vendor}" = "Microsoft Corporation" -a "${product_name}" = "Virtual Machine"
|
||||||
then
|
then
|
||||||
%if %{use_systemd}
|
%if %{use_systemd}
|
||||||
%{service_add_post %{hv_kvp_daemon}.service}
|
: nothing to do in case of systemd
|
||||||
%{service_add_post %{hv_vss_daemon}.service}
|
|
||||||
%else
|
%else
|
||||||
echo "Enabling %{hv_kvp_daemon} on '${product_name}' from '${board_vendor}'"
|
echo "Enabling %{hv_kvp_daemon} on '${product_name}' from '${board_vendor}'"
|
||||||
%{insserv_force_if_yast %{hv_kvp_daemon}}
|
%{insserv_force_if_yast %{hv_kvp_daemon}}
|
||||||
@ -215,8 +266,7 @@ fi
|
|||||||
|
|
||||||
%preun
|
%preun
|
||||||
%if %{use_systemd}
|
%if %{use_systemd}
|
||||||
%{service_del_preun %{hv_kvp_daemon}.service}
|
: nothing to do in case of systemd
|
||||||
%{service_del_preun %{hv_vss_daemon}.service}
|
|
||||||
%else
|
%else
|
||||||
%stop_on_removal %{hv_kvp_daemon}
|
%stop_on_removal %{hv_kvp_daemon}
|
||||||
%stop_on_removal %{hv_vss_daemon}
|
%stop_on_removal %{hv_vss_daemon}
|
||||||
@ -225,8 +275,7 @@ fi
|
|||||||
%postun
|
%postun
|
||||||
# no restart on update because the daemon can not be restarted
|
# no restart on update because the daemon can not be restarted
|
||||||
%if %{use_systemd}
|
%if %{use_systemd}
|
||||||
%{service_del_postun %{hv_kvp_daemon}.service}
|
: nothing to do in case of systemd
|
||||||
%{service_del_postun %{hv_vss_daemon}.service}
|
|
||||||
%else
|
%else
|
||||||
%insserv_cleanup
|
%insserv_cleanup
|
||||||
%endif
|
%endif
|
||||||
|
200
hyper-v.tools.hv.hv_fcopy_daemon.c
Normal file
200
hyper-v.tools.hv.hv_fcopy_daemon.c
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
/*
|
||||||
|
* 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 = 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user