Compare commits

...

No commits in common. 'c9' and 'i10c-beta' have entirely different histories.

@ -1,24 +0,0 @@
From 88be69d62a01b9ac233de7f68118c948623c6f0a Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Thu, 14 Nov 2019 09:45:44 +0100
Subject: Do not set NM_CONTROLLED=no
---
hv_set_ifconfig.sh | 1 -
1 file changed, 1 deletion(-)
diff --git a/hv_set_ifconfig.sh b/hv_set_ifconfig.sh
index 7ed9f85..18b27cc 100644
--- a/hv_set_ifconfig.sh
+++ b/hv_set_ifconfig.sh
@@ -51,7 +51,6 @@
echo "IPV6INIT=yes" >> $1
-echo "NM_CONTROLLED=no" >> $1
echo "PEERDNS=yes" >> $1
echo "ONBOOT=yes" >> $1
--
2.27.0

@ -1,345 +0,0 @@
From f20c2a3298ceae7536c06bd08a5c571ebfa8cce4 Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Thu, 6 May 2021 12:50:43 +0200
Subject: Update C files and scripts to kernel version 5.7-rc1
(cherry-picked from RHEL 8.4.0 commit b0a20fac0e74b0b3eecc20ffe74006e7877da352)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
hv_fcopy_daemon.c | 37 +++++++++++++++++++++++++++++++-----
hv_get_dhcp_info.sh | 2 +-
hv_kvp_daemon.c | 35 ++++++++++++++++++++--------------
hv_set_ifconfig.sh | 2 +-
hv_vss_daemon.c | 46 ++++++++++++++++++++++++++++++++++-----------
5 files changed, 90 insertions(+), 32 deletions(-)
diff --git a/hv_fcopy_daemon.c b/hv_fcopy_daemon.c
index aea2d91..16d629b 100644
--- a/hv_fcopy_daemon.c
+++ b/hv_fcopy_daemon.c
@@ -80,6 +80,8 @@ static int hv_start_fcopy(struct hv_start_fcopy *smsg)
error = 0;
done:
+ if (error)
+ target_fname[0] = '\0';
return error;
}
@@ -108,15 +110,29 @@ static int hv_copy_data(struct hv_do_fcopy *cpmsg)
return ret;
}
+/*
+ * Reset target_fname to "" in the two below functions for hibernation: if
+ * the fcopy operation is aborted by hibernation, the daemon should remove the
+ * partially-copied file; to achieve this, the hv_utils driver always fakes a
+ * CANCEL_FCOPY message upon suspend, and later when the VM resumes back,
+ * the daemon calls hv_copy_cancel() to remove the file; if a file is copied
+ * successfully before suspend, hv_copy_finished() must reset target_fname to
+ * avoid that the file can be incorrectly removed upon resume, since the faked
+ * CANCEL_FCOPY message is spurious in this case.
+ */
static int hv_copy_finished(void)
{
close(target_fd);
+ target_fname[0] = '\0';
return 0;
}
static int hv_copy_cancel(void)
{
close(target_fd);
- unlink(target_fname);
+ if (strlen(target_fname) > 0) {
+ unlink(target_fname);
+ target_fname[0] = '\0';
+ }
return 0;
}
@@ -131,7 +147,7 @@ void print_usage(char *argv[])
int main(int argc, char *argv[])
{
- int fcopy_fd;
+ int fcopy_fd = -1;
int error;
int daemonize = 1, long_index = 0, opt;
int version = FCOPY_CURRENT_VERSION;
@@ -141,7 +157,7 @@ int main(int argc, char *argv[])
struct hv_do_fcopy copy;
__u32 kernel_modver;
} buffer = { };
- int in_handshake = 1;
+ int in_handshake;
static struct option long_options[] = {
{"help", no_argument, 0, 'h' },
@@ -170,6 +186,12 @@ int main(int argc, char *argv[])
openlog("HV_FCOPY", 0, LOG_USER);
syslog(LOG_INFO, "starting; pid is:%d", getpid());
+reopen_fcopy_fd:
+ if (fcopy_fd != -1)
+ close(fcopy_fd);
+ /* Remove any possible partially-copied file on error */
+ hv_copy_cancel();
+ in_handshake = 1;
fcopy_fd = open("/dev/vmbus/hv_fcopy", O_RDWR);
if (fcopy_fd < 0) {
@@ -196,7 +218,7 @@ int main(int argc, char *argv[])
len = pread(fcopy_fd, &buffer, sizeof(buffer), 0);
if (len < 0) {
syslog(LOG_ERR, "pread failed: %s", strerror(errno));
- exit(EXIT_FAILURE);
+ goto reopen_fcopy_fd;
}
if (in_handshake) {
@@ -231,9 +253,14 @@ int main(int argc, char *argv[])
}
+ /*
+ * pwrite() may return an error due to the faked CANCEL_FCOPY
+ * message upon hibernation. Ignore the error by resetting the
+ * dev file, i.e. closing and re-opening it.
+ */
if (pwrite(fcopy_fd, &error, sizeof(int), 0) != sizeof(int)) {
syslog(LOG_ERR, "pwrite failed: %s", strerror(errno));
- exit(EXIT_FAILURE);
+ goto reopen_fcopy_fd;
}
}
}
diff --git a/hv_get_dhcp_info.sh b/hv_get_dhcp_info.sh
index c38686c..2f2a3c7 100644
--- a/hv_get_dhcp_info.sh
+++ b/hv_get_dhcp_info.sh
@@ -13,7 +13,7 @@
# the script prints the string "Disabled" to stdout.
#
# Each Distro is expected to implement this script in a distro specific
-# fashion. For instance on Distros that ship with Network Manager enabled,
+# fashion. For instance, on Distros that ship with Network Manager enabled,
# this script can be based on the Network Manager APIs for retrieving DHCP
# information.
diff --git a/hv_kvp_daemon.c b/hv_kvp_daemon.c
index e9ef4ca..0e5f14a 100644
--- a/hv_kvp_daemon.c
+++ b/hv_kvp_daemon.c
@@ -76,7 +76,7 @@ enum {
DNS
};
-static int in_hand_shake = 1;
+static int in_hand_shake;
static char *os_name = "";
static char *os_major = "";
@@ -1360,7 +1360,7 @@ void print_usage(char *argv[])
int main(int argc, char *argv[])
{
- int kvp_fd, len;
+ int kvp_fd = -1, len;
int error;
struct pollfd pfd;
char *p;
@@ -1400,14 +1400,6 @@ int main(int argc, char *argv[])
openlog("KVP", 0, LOG_USER);
syslog(LOG_INFO, "KVP starting; pid is:%d", getpid());
- kvp_fd = open("/dev/vmbus/hv_kvp", O_RDWR | O_CLOEXEC);
-
- if (kvp_fd < 0) {
- syslog(LOG_ERR, "open /dev/vmbus/hv_kvp failed; error: %d %s",
- errno, strerror(errno));
- exit(EXIT_FAILURE);
- }
-
/*
* Retrieve OS release information.
*/
@@ -1423,6 +1415,18 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
+reopen_kvp_fd:
+ if (kvp_fd != -1)
+ close(kvp_fd);
+ in_hand_shake = 1;
+ kvp_fd = open("/dev/vmbus/hv_kvp", O_RDWR | O_CLOEXEC);
+
+ if (kvp_fd < 0) {
+ syslog(LOG_ERR, "open /dev/vmbus/hv_kvp failed; error: %d %s",
+ errno, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
/*
* Register ourselves with the kernel.
*/
@@ -1457,8 +1461,7 @@ int main(int argc, char *argv[])
syslog(LOG_ERR, "read failed; error:%d %s",
errno, strerror(errno));
- close(kvp_fd);
- return EXIT_FAILURE;
+ goto reopen_kvp_fd;
}
/*
@@ -1617,13 +1620,17 @@ int main(int argc, char *argv[])
break;
}
- /* Send the value back to the kernel. */
+ /*
+ * Send the value back to the kernel. Note: the write() may
+ * return an error due to hibernation; we can ignore the error
+ * by resetting the dev file, i.e. closing and re-opening it.
+ */
kvp_done:
len = write(kvp_fd, hv_msg, sizeof(struct hv_kvp_msg));
if (len != sizeof(struct hv_kvp_msg)) {
syslog(LOG_ERR, "write failed; error: %d %s", errno,
strerror(errno));
- exit(EXIT_FAILURE);
+ goto reopen_kvp_fd;
}
}
diff --git a/hv_set_ifconfig.sh b/hv_set_ifconfig.sh
index 18b27cc..3dd064c 100644
--- a/hv_set_ifconfig.sh
+++ b/hv_set_ifconfig.sh
@@ -12,7 +12,7 @@
# be used to configure the interface.
#
# Each Distro is expected to implement this script in a distro specific
-# fashion. For instance on Distros that ship with Network Manager enabled,
+# fashion. For instance, on Distros that ship with Network Manager enabled,
# this script can be based on the Network Manager APIs for configuring the
# interface.
#
diff --git a/hv_vss_daemon.c b/hv_vss_daemon.c
index 92902a8..29a1e48 100644
--- a/hv_vss_daemon.c
+++ b/hv_vss_daemon.c
@@ -28,6 +28,8 @@
#include <stdbool.h>
#include <dirent.h>
+static bool fs_frozen;
+
/* Don't use syslog() in the function since that can cause write to disk */
static int vss_do_freeze(char *dir, unsigned int cmd)
{
@@ -155,16 +157,22 @@ static int vss_operate(int operation)
continue;
}
error |= vss_do_freeze(ent->mnt_dir, cmd);
- if (error && operation == VSS_OP_FREEZE)
- goto err;
+ if (operation == VSS_OP_FREEZE) {
+ if (error)
+ goto err;
+ fs_frozen = true;
+ }
}
endmntent(mounts);
if (root_seen) {
error |= vss_do_freeze("/", cmd);
- if (error && operation == VSS_OP_FREEZE)
- goto err;
+ if (operation == VSS_OP_FREEZE) {
+ if (error)
+ goto err;
+ fs_frozen = true;
+ }
}
goto out;
@@ -175,6 +183,7 @@ err:
endmntent(mounts);
}
vss_operate(VSS_OP_THAW);
+ fs_frozen = false;
/* Call syslog after we thaw all filesystems */
if (ent)
syslog(LOG_ERR, "FREEZE of %s failed; error:%d %s",
@@ -196,13 +205,13 @@ void print_usage(char *argv[])
int main(int argc, char *argv[])
{
- int vss_fd, len;
+ int vss_fd = -1, len;
int error;
struct pollfd pfd;
int op;
struct hv_vss_msg vss_msg[1];
int daemonize = 1, long_index = 0, opt;
- int in_handshake = 1;
+ int in_handshake;
__u32 kernel_modver;
static struct option long_options[] = {
@@ -232,6 +241,18 @@ int main(int argc, char *argv[])
openlog("Hyper-V VSS", 0, LOG_USER);
syslog(LOG_INFO, "VSS starting; pid is:%d", getpid());
+reopen_vss_fd:
+ if (vss_fd != -1)
+ close(vss_fd);
+ if (fs_frozen) {
+ if (vss_operate(VSS_OP_THAW) || fs_frozen) {
+ syslog(LOG_ERR, "failed to thaw file system: err=%d",
+ errno);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ in_handshake = 1;
vss_fd = open("/dev/vmbus/hv_vss", O_RDWR);
if (vss_fd < 0) {
syslog(LOG_ERR, "open /dev/vmbus/hv_vss failed; error: %d %s",
@@ -247,8 +268,7 @@ int main(int argc, char *argv[])
if (len < 0) {
syslog(LOG_ERR, "registration to kernel failed; error: %d %s",
errno, strerror(errno));
- close(vss_fd);
- exit(EXIT_FAILURE);
+ goto reopen_vss_fd;
}
pfd.fd = vss_fd;
@@ -312,14 +332,18 @@ int main(int argc, char *argv[])
default:
syslog(LOG_ERR, "Illegal op:%d\n", op);
}
+
+ /*
+ * The write() may return an error due to the faked VSS_OP_THAW
+ * message upon hibernation. Ignore the error by resetting the
+ * dev file, i.e. closing and re-opening it.
+ */
vss_msg->error = error;
len = write(vss_fd, vss_msg, sizeof(struct hv_vss_msg));
if (len != sizeof(struct hv_vss_msg)) {
syslog(LOG_ERR, "write failed; error: %d %s", errno,
strerror(errno));
-
- if (op == VSS_OP_FREEZE)
- vss_operate(VSS_OP_THAW);
+ goto reopen_vss_fd;
}
}
--
2.27.0

@ -1,56 +0,0 @@
From 6ed9946f9a4f1a01846add2279e8d0640c1c2f1c Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Thu, 6 May 2021 12:53:58 +0200
Subject: tools: hv: change http to https in hv_kvp_daemon.c
The patch has no functional change. Only changes the URL pointed to
in one of the comments
commit fa52a4b2d0ab416508538bb47a95167d4c94caac
Author: Alexander A. Klimov <grandmaster@al2klimov.de>
Date: Sun Jul 5 23:44:57 2020 +0200
tools: hv: change http to https in hv_kvp_daemon.c
Rationale:
Reduces attack surface on kernel devs opening the links for MITM
as HTTPS traffic is much harder to manipulate.
Deterministic algorithm:
For each file:
If not .svg:
For each line:
If doesn't contain `\bxmlns\b`:
For each link, `\bhttp://[^# \t\r\n]*(?:\w|/)`:
If both the HTTP and HTTPS versions
return 200 OK and serve the same content:
Replace HTTP with HTTPS.
Signed-off-by: Alexander A. Klimov <grandmaster@al2klimov.de>
Link: https://lore.kernel.org/r/20200705214457.28433-1-grandmaster@al2klimov.de
[ wei: change subject line to be more specific ]
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Signed-off-by: Mohammed Gamal <mgamal@redhat.com>
(cherry-picked from rhel 8.4.0 commit e956573)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
hv_kvp_daemon.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hv_kvp_daemon.c b/hv_kvp_daemon.c
index 0e5f14a..c06c94d 100644
--- a/hv_kvp_daemon.c
+++ b/hv_kvp_daemon.c
@@ -437,7 +437,7 @@ void kvp_get_os_info(void)
/*
* Parse the /etc/os-release file if present:
- * http://www.freedesktop.org/software/systemd/man/os-release.html
+ * https://www.freedesktop.org/software/systemd/man/os-release.html
*/
file = fopen("/etc/os-release", "r");
if (file != NULL) {
--
2.27.0

@ -1,16 +1,26 @@
From a13aa83d1b5bb4b6ce4396aef3457b48695b7c41 Mon Sep 17 00:00:00 2001
From e24f15d5aa258daabb2c34a7b9fed348ac63705d Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Thu, 6 May 2021 12:53:31 +0200
Subject: Add vmbus_testing tool build files
Subject: [PATCH 03/14] Add vmbus_testing tool build files
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-MergeRequest: 9: Synchronize RHEL 9 changes to RHEL 10
RH-Jira: RHEL-40107 RHEL-40679
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Commit: [3/14] 384e79f48e6f4665f90fd3b2b17fcaef2178a674 (mrezanin/centos-git-hyperv-daemons)
Add the vmbus_testing tool to redhat build dirs
(cherry-pick from rhel 8.4.0 commit d8ca5e0)
Signed-off-by: Mohammed Gamal <mgamal@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
patch_name: 0005-Add-vmbus_testing-tool-build-files.patch
present_in_specfile: true
location_in_specfile: 5
---
.distro/hyperv-daemons.spec.template | 2 +
vmbus_testing | 376 +++++++++++++++++++++++++++
.distro/hyperv-daemons.spec | 2 +
vmbus_testing | 376 ++++++++++++++++++++++++++++++++++++
2 files changed, 378 insertions(+)
create mode 100755 vmbus_testing
@ -397,5 +407,5 @@ index 0000000..e721290
+if __name__ == "__main__":
+ main()
--
2.27.0
2.39.3

@ -0,0 +1,68 @@
From 935df801defcb3f459891e180e66065030d11612 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Tue, 10 Oct 2023 11:50:30 +0530
Subject: [PATCH 13/14] Changes for adding keyfile support in RHEL specific
script
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-MergeRequest: 9: Synchronize RHEL 9 changes to RHEL 10
RH-Jira: RHEL-40107 RHEL-40679
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Commit: [13/14] 0dec80310c49a5ccbc6b030ba6c575046b21b60f (mrezanin/centos-git-hyperv-daemons)
Some adjustments to the RHEL specific customization script in order to support
Network Manager keyfiles. These changes were tested internally by Red Hat QE.
These changes are mostly trivial and are not pushed upstream at this momemnt.
See also https://issues.redhat.com/browse/RHEL-14505
Signed-off-by: Ani Sinha <anisinha@redhat.com>
patch_name: hpvd-Changes-for-adding-keyfile-support-in-RHEL-specific-.patch
present_in_specfile: true
location_in_specfile: 16
---
hv_set_ifconfig.sh | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/hv_set_ifconfig.sh b/hv_set_ifconfig.sh
index 9c2ee30..0bdf2bc 100644
--- a/hv_set_ifconfig.sh
+++ b/hv_set_ifconfig.sh
@@ -74,19 +74,22 @@
# call.
#
+# This is RHEL specific bash script that configures NM keyfiles.
+# ifcfg files passed as the first argument to this script remains untouched.
+if [ -z "$2" ]; then
+ echo "No input NM keyfile. Exiting!"
+ exit 1
+fi
-echo "IPV6INIT=yes" >> $1
-echo "PEERDNS=yes" >> $1
-echo "ONBOOT=yes" >> $1
+sed -i '/\[ipv4\]/a ignore-auto-dns=false' $2
+sed -i '/\[connection\]/a autoconnect=true' $2
-#Unlike older sysconfig scripts, NetworkManager expects GATEWAYx=ipaddr for all values of x.
-#So the first gateway is GATEWAY0 instead of GATEWAY. Other values should remain unchanged.
-#Workaround this by replacing GATEWAY= with GATEWAY0=.
-sed -i "s/GATEWAY=/GATEWAY0=/" $1
+filename="${2##*/}"
+chmod 600 $2
+cp $2 /etc/NetworkManager/system-connections/
-cp $1 /etc/sysconfig/network-scripts/
+nmcli connection load "/etc/NetworkManager/system-connections/${filename}"
+nmcli connection up filename "/etc/NetworkManager/system-connections/${filename}"
-filename="${1##*/}"
-nmcli connection load "/etc/sysconfig/network-scripts/${filename}"
-nmcli connection up filename "/etc/sysconfig/network-scripts/${filename}"
+exit 0
--
2.39.3

@ -0,0 +1,33 @@
From 45c529405a747e7be7cc229913393fa34f5cd4ff Mon Sep 17 00:00:00 2001
From: Miroslav Rezanina <mrezanin@redhat.com>
Date: Thu, 14 Nov 2019 09:45:44 +0100
Subject: [PATCH 02/14] Do not set NM_CONTROLLED=no
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-MergeRequest: 9: Synchronize RHEL 9 changes to RHEL 10
RH-Jira: RHEL-40107 RHEL-40679
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Commit: [2/14] 3873d86dfc8a13e160b82cbdf3e9aaa52eedb37f (mrezanin/centos-git-hyperv-daemons)
patch_name: 0002-Do-not-set-NM_CONTROLLED-no.patch
present_in_specfile: true
location_in_specfile: 2
---
hv_set_ifconfig.sh | 1 -
1 file changed, 1 deletion(-)
diff --git a/hv_set_ifconfig.sh b/hv_set_ifconfig.sh
index d10fe35..3dd064c 100644
--- a/hv_set_ifconfig.sh
+++ b/hv_set_ifconfig.sh
@@ -51,7 +51,6 @@
echo "IPV6INIT=yes" >> $1
-echo "NM_CONTROLLED=no" >> $1
echo "PEERDNS=yes" >> $1
echo "ONBOOT=yes" >> $1
--
2.39.3

@ -1,14 +1,17 @@
From 3d234bcdb4d40b42923688514a2fb5d1cb8b3314 Mon Sep 17 00:00:00 2001
From 71c04766e4b8a4edfa8c645d30cea48f825cc1e9 Mon Sep 17 00:00:00 2001
From: Till Maas <timaas@redhat.com>
Date: Tue, 14 Dec 2021 08:07:40 +0000
Subject: [PATCH 2/2] Use filename for connection profile
Subject: [PATCH 05/14] Use filename for connection profile
RH-Author: Till Maas <None>
RH-MergeRequest: 2: hv_set_ifconfig.sh: Use nmcli commands
RH-Commit: [2/2] 6b6f37ba159b0614b75fcfc02f0513af116711c2 (timaas/hyperv-daemons)
RH-Bugzilla: 2026371
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-MergeRequest: 9: Synchronize RHEL 9 changes to RHEL 10
RH-Jira: RHEL-40107 RHEL-40679
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Commit: [5/14] e91a7aeb17973de8526f325b44cda5af733c43ee (mrezanin/centos-git-hyperv-daemons)
patch_name: hpvd-Use-filename-for-connection-profile.patch
present_in_specfile: true
location_in_specfile: 8
---
hv_set_ifconfig.sh | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
@ -27,5 +30,5 @@ index 5a64efe..146829b 100644
+nmcli connection load "/etc/sysconfig/network-scripts/${filename}"
+nmcli connection up filename "/etc/sysconfig/network-scripts/${filename}"
--
2.27.0
2.39.3

@ -0,0 +1,338 @@
From cc43c1ad250ed39ee7d5f5459049b29f1c4a6f42 Mon Sep 17 00:00:00 2001
From: Shradha Gupta <shradhagupta@linux.microsoft.com>
Date: Fri, 22 Mar 2024 06:46:02 -0700
Subject: [PATCH 12/14] hv/hv_kvp_daemon: Handle IPv4 and Ipv6 combination for
keyfile format
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-MergeRequest: 9: Synchronize RHEL 9 changes to RHEL 10
RH-Jira: RHEL-40107 RHEL-40679
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Commit: [12/14] 936263af9ba1441d37661bfa356c45db782df926 (mrezanin/centos-git-hyperv-daemons)
If the network configuration strings are passed as a combination of IPv4
and IPv6 addresses, the current KVP daemon does not handle processing for
the keyfile configuration format.
With these changes, the keyfile config generation logic scans through the
list twice to generate IPv4 and IPv6 sections for the configuration files
to handle this support.
Testcases ran:Rhel 9, Hyper-V VMs
(IPv4 only, IPv6 only, IPv4 and IPv6 combination)
Cherry-picked from Linux kernel upstream commit
f971f6dd3742d2 ("hv/hv_kvp_daemon: Handle IPv4 and Ipv6 combination for keyfile format")
Co-developed-by: Ani Sinha <anisinha@redhat.com>
Signed-off-by: Ani Sinha <anisinha@redhat.com>
Signed-off-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
Reviewed-by: Easwar Hariharan <eahariha@linux.microsoft.com>
Tested-by: Ani Sinha <anisinha@redhat.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Link: https://lore.kernel.org/r/1711115162-11629-1-git-send-email-shradhagupta@linux.microsoft.com
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Message-ID: <1711115162-11629-1-git-send-email-shradhagupta@linux.microsoft.com>
patch_name: hpvd-hv-hv_kvp_daemon-Handle-IPv4-and-Ipv6-combination-fo.patch
present_in_specfile: true
location_in_specfile: 15
---
hv_kvp_daemon.c | 213 ++++++++++++++++++++++++++++++++++++++----------
1 file changed, 172 insertions(+), 41 deletions(-)
diff --git a/hv_kvp_daemon.c b/hv_kvp_daemon.c
index 318e2da..ae57bf6 100644
--- a/hv_kvp_daemon.c
+++ b/hv_kvp_daemon.c
@@ -76,6 +76,12 @@ enum {
DNS
};
+enum {
+ IPV4 = 1,
+ IPV6,
+ IP_TYPE_MAX
+};
+
static int in_hand_shake;
static char *os_name = "";
@@ -102,6 +108,11 @@ static struct utsname uts_buf;
#define MAX_FILE_NAME 100
#define ENTRIES_PER_BLOCK 50
+/*
+ * Change this entry if the number of addresses increases in future
+ */
+#define MAX_IP_ENTRIES 64
+#define OUTSTR_BUF_SIZE ((INET6_ADDRSTRLEN + 1) * MAX_IP_ENTRIES)
struct kvp_record {
char key[HV_KVP_EXCHANGE_MAX_KEY_SIZE];
@@ -1171,6 +1182,18 @@ static int process_ip_string(FILE *f, char *ip_string, int type)
return 0;
}
+int ip_version_check(const char *input_addr)
+{
+ struct in6_addr addr;
+
+ if (inet_pton(AF_INET, input_addr, &addr))
+ return IPV4;
+ else if (inet_pton(AF_INET6, input_addr, &addr))
+ return IPV6;
+
+ return -EINVAL;
+}
+
/*
* Only IPv4 subnet strings needs to be converted to plen
* For IPv6 the subnet is already privided in plen format
@@ -1197,14 +1220,75 @@ static int kvp_subnet_to_plen(char *subnet_addr_str)
return plen;
}
+static int process_dns_gateway_nm(FILE *f, char *ip_string, int type,
+ int ip_sec)
+{
+ char addr[INET6_ADDRSTRLEN], *output_str;
+ int ip_offset = 0, error = 0, ip_ver;
+ char *param_name;
+
+ if (type == DNS)
+ param_name = "dns";
+ else if (type == GATEWAY)
+ param_name = "gateway";
+ else
+ return -EINVAL;
+
+ output_str = (char *)calloc(OUTSTR_BUF_SIZE, sizeof(char));
+ if (!output_str)
+ return -ENOMEM;
+
+ while (1) {
+ memset(addr, 0, sizeof(addr));
+
+ if (!parse_ip_val_buffer(ip_string, &ip_offset, addr,
+ (MAX_IP_ADDR_SIZE * 2)))
+ break;
+
+ ip_ver = ip_version_check(addr);
+ if (ip_ver < 0)
+ continue;
+
+ if ((ip_ver == IPV4 && ip_sec == IPV4) ||
+ (ip_ver == IPV6 && ip_sec == IPV6)) {
+ /*
+ * do a bound check to avoid out-of bound writes
+ */
+ if ((OUTSTR_BUF_SIZE - strlen(output_str)) >
+ (strlen(addr) + 1)) {
+ strncat(output_str, addr,
+ OUTSTR_BUF_SIZE -
+ strlen(output_str) - 1);
+ strncat(output_str, ",",
+ OUTSTR_BUF_SIZE -
+ strlen(output_str) - 1);
+ }
+ } else {
+ continue;
+ }
+ }
+
+ if (strlen(output_str)) {
+ /*
+ * This is to get rid of that extra comma character
+ * in the end of the string
+ */
+ output_str[strlen(output_str) - 1] = '\0';
+ error = fprintf(f, "%s=%s\n", param_name, output_str);
+ }
+
+ free(output_str);
+ return error;
+}
+
static int process_ip_string_nm(FILE *f, char *ip_string, char *subnet,
- int is_ipv6)
+ int ip_sec)
{
char addr[INET6_ADDRSTRLEN];
char subnet_addr[INET6_ADDRSTRLEN];
- int error, i = 0;
+ int error = 0, i = 0;
int ip_offset = 0, subnet_offset = 0;
- int plen;
+ int plen, ip_ver;
memset(addr, 0, sizeof(addr));
memset(subnet_addr, 0, sizeof(subnet_addr));
@@ -1216,10 +1300,16 @@ static int process_ip_string_nm(FILE *f, char *ip_string, char *subnet,
subnet_addr,
(MAX_IP_ADDR_SIZE *
2))) {
- if (!is_ipv6)
+ ip_ver = ip_version_check(addr);
+ if (ip_ver < 0)
+ continue;
+
+ if (ip_ver == IPV4 && ip_sec == IPV4)
plen = kvp_subnet_to_plen((char *)subnet_addr);
- else
+ else if (ip_ver == IPV6 && ip_sec == IPV6)
plen = atoi(subnet_addr);
+ else
+ continue;
if (plen < 0)
return plen;
@@ -1233,17 +1323,16 @@ static int process_ip_string_nm(FILE *f, char *ip_string, char *subnet,
memset(subnet_addr, 0, sizeof(subnet_addr));
}
- return 0;
+ return error;
}
static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
{
- int error = 0;
+ int error = 0, ip_ver;
char if_filename[PATH_MAX];
char nm_filename[PATH_MAX];
FILE *ifcfg_file, *nmfile;
char cmd[PATH_MAX];
- int is_ipv6 = 0;
char *mac_addr;
int str_len;
@@ -1421,52 +1510,94 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
if (error)
goto setval_error;
- if (new_val->addr_family & ADDR_FAMILY_IPV6) {
- error = fprintf(nmfile, "\n[ipv6]\n");
- if (error < 0)
- goto setval_error;
- is_ipv6 = 1;
- } else {
- error = fprintf(nmfile, "\n[ipv4]\n");
- if (error < 0)
- goto setval_error;
- }
-
/*
* Now we populate the keyfile format
+ *
+ * The keyfile format expects the IPv6 and IPv4 configuration in
+ * different sections. Therefore we iterate through the list twice,
+ * once to populate the IPv4 section and the next time for IPv6
*/
+ ip_ver = IPV4;
+ do {
+ if (ip_ver == IPV4) {
+ error = fprintf(nmfile, "\n[ipv4]\n");
+ if (error < 0)
+ goto setval_error;
+ } else {
+ error = fprintf(nmfile, "\n[ipv6]\n");
+ if (error < 0)
+ goto setval_error;
+ }
- if (new_val->dhcp_enabled) {
- error = kvp_write_file(nmfile, "method", "", "auto");
- if (error < 0)
- goto setval_error;
- } else {
- error = kvp_write_file(nmfile, "method", "", "manual");
+ /*
+ * Write the configuration for ipaddress, netmask, gateway and
+ * name services
+ */
+ error = process_ip_string_nm(nmfile, (char *)new_val->ip_addr,
+ (char *)new_val->sub_net,
+ ip_ver);
if (error < 0)
goto setval_error;
- }
- /*
- * Write the configuration for ipaddress, netmask, gateway and
- * name services
- */
- error = process_ip_string_nm(nmfile, (char *)new_val->ip_addr,
- (char *)new_val->sub_net, is_ipv6);
- if (error < 0)
- goto setval_error;
+ /*
+ * As dhcp_enabled is only valid for ipv4, we do not set dhcp
+ * methods for ipv6 based on dhcp_enabled flag.
+ *
+ * For ipv4, set method to manual only when dhcp_enabled is
+ * false and specific ipv4 addresses are configured. If neither
+ * dhcp_enabled is true and no ipv4 addresses are configured,
+ * set method to 'disabled'.
+ *
+ * For ipv6, set method to manual when we configure ipv6
+ * addresses. Otherwise set method to 'auto' so that SLAAC from
+ * RA may be used.
+ */
+ if (ip_ver == IPV4) {
+ if (new_val->dhcp_enabled) {
+ error = kvp_write_file(nmfile, "method", "",
+ "auto");
+ if (error < 0)
+ goto setval_error;
+ } else if (error) {
+ error = kvp_write_file(nmfile, "method", "",
+ "manual");
+ if (error < 0)
+ goto setval_error;
+ } else {
+ error = kvp_write_file(nmfile, "method", "",
+ "disabled");
+ if (error < 0)
+ goto setval_error;
+ }
+ } else if (ip_ver == IPV6) {
+ if (error) {
+ error = kvp_write_file(nmfile, "method", "",
+ "manual");
+ if (error < 0)
+ goto setval_error;
+ } else {
+ error = kvp_write_file(nmfile, "method", "",
+ "auto");
+ if (error < 0)
+ goto setval_error;
+ }
+ }
- /* we do not want ipv4 addresses in ipv6 section and vice versa */
- if (is_ipv6 != is_ipv4((char *)new_val->gate_way)) {
- error = fprintf(nmfile, "gateway=%s\n", (char *)new_val->gate_way);
+ error = process_dns_gateway_nm(nmfile,
+ (char *)new_val->gate_way,
+ GATEWAY, ip_ver);
if (error < 0)
goto setval_error;
- }
- if (is_ipv6 != is_ipv4((char *)new_val->dns_addr)) {
- error = fprintf(nmfile, "dns=%s\n", (char *)new_val->dns_addr);
+ error = process_dns_gateway_nm(nmfile,
+ (char *)new_val->dns_addr, DNS,
+ ip_ver);
if (error < 0)
goto setval_error;
- }
+
+ ip_ver++;
+ } while (ip_ver < IP_TYPE_MAX);
+
fclose(nmfile);
fclose(ifcfg_file);
--
2.39.3

@ -0,0 +1,103 @@
From a8335c9675d22f8ed51a98e2f6b0f6f684d07793 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Mon, 16 Oct 2023 19:03:33 +0530
Subject: [PATCH 11/14] hv/hv_kvp_daemon: Some small fixes for handling NM
keyfiles
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-MergeRequest: 9: Synchronize RHEL 9 changes to RHEL 10
RH-Jira: RHEL-40107 RHEL-40679
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Commit: [11/14] 55156e8fdd215ce1308887ea463a17ba614b1837 (mrezanin/centos-git-hyperv-daemons)
Some small fixes:
- lets make sure we are not adding ipv4 addresses in ipv6 section in
keyfile and vice versa.
- ADDR_FAMILY_IPV6 is a bit in addr_family. Test that bit instead of
checking the whole value of addr_family.
- Some trivial fixes in hv_set_ifconfig.sh.
These fixes are proposed after doing some internal testing at Red Hat.
Cherry-picked from upstream linux
kernel commit c3803203bc5ec910a ("hv/hv_kvp_daemon: Some small fixes for handling NM keyfiles")
CC: Shradha Gupta <shradhagupta@linux.microsoft.com>
CC: Saurabh Sengar <ssengar@linux.microsoft.com>
Fixes: 42999c904612 ("hv/hv_kvp_daemon:Support for keyfile based connection profile")
Signed-off-by: Ani Sinha <anisinha@redhat.com>
Reviewed-by: Shradha Gupta <Shradhagupta@linux.microsoft.com>
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Message-ID: <20231016133122.2419537-1-anisinha@redhat.com>
patch_name: hpvd-hv-hv_kvp_daemon-Some-small-fixes-for-handling-NM-ke.patch
present_in_specfile: true
location_in_specfile: 14
---
hv_kvp_daemon.c | 20 ++++++++++++--------
hv_set_ifconfig.sh | 4 ++--
2 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/hv_kvp_daemon.c b/hv_kvp_daemon.c
index 264eeb9..318e2da 100644
--- a/hv_kvp_daemon.c
+++ b/hv_kvp_daemon.c
@@ -1421,7 +1421,7 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
if (error)
goto setval_error;
- if (new_val->addr_family == ADDR_FAMILY_IPV6) {
+ if (new_val->addr_family & ADDR_FAMILY_IPV6) {
error = fprintf(nmfile, "\n[ipv6]\n");
if (error < 0)
goto setval_error;
@@ -1455,14 +1455,18 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
if (error < 0)
goto setval_error;
- error = fprintf(nmfile, "gateway=%s\n", (char *)new_val->gate_way);
- if (error < 0)
- goto setval_error;
-
- error = fprintf(nmfile, "dns=%s\n", (char *)new_val->dns_addr);
- if (error < 0)
- goto setval_error;
+ /* we do not want ipv4 addresses in ipv6 section and vice versa */
+ if (is_ipv6 != is_ipv4((char *)new_val->gate_way)) {
+ error = fprintf(nmfile, "gateway=%s\n", (char *)new_val->gate_way);
+ if (error < 0)
+ goto setval_error;
+ }
+ if (is_ipv6 != is_ipv4((char *)new_val->dns_addr)) {
+ error = fprintf(nmfile, "dns=%s\n", (char *)new_val->dns_addr);
+ if (error < 0)
+ goto setval_error;
+ }
fclose(nmfile);
fclose(ifcfg_file);
diff --git a/hv_set_ifconfig.sh b/hv_set_ifconfig.sh
index 35aae6f..9c2ee30 100644
--- a/hv_set_ifconfig.sh
+++ b/hv_set_ifconfig.sh
@@ -53,7 +53,7 @@
# or "manual" if no boot-time protocol should be used)
#
# address1=ipaddr1/plen
-# address=ipaddr2/plen
+# address2=ipaddr2/plen
#
# gateway=gateway1;gateway2
#
@@ -61,7 +61,7 @@
#
# [ipv6]
# address1=ipaddr1/plen
-# address2=ipaddr1/plen
+# address2=ipaddr2/plen
#
# gateway=gateway1;gateway2
#
--
2.39.3

@ -0,0 +1,429 @@
From cdf838e027ed7b6438dc86df6329bf46a7541b4f Mon Sep 17 00:00:00 2001
From: Shradha Gupta <shradhagupta@linux.microsoft.com>
Date: Mon, 9 Oct 2023 03:38:40 -0700
Subject: [PATCH 10/14] hv/hv_kvp_daemon:Support for keyfile based connection
profile
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-MergeRequest: 9: Synchronize RHEL 9 changes to RHEL 10
RH-Jira: RHEL-40107 RHEL-40679
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Commit: [10/14] 16745685ef5d6c90f95acdd665a348ce8f30a684 (mrezanin/centos-git-hyperv-daemons)
Ifcfg config file support in NetworkManger is deprecated. This patch
provides support for the new keyfile config format for connection
profiles in NetworkManager. The patch modifies the hv_kvp_daemon code
to generate the new network configuration in keyfile
format(.ini-style format) along with a ifcfg format configuration.
The ifcfg format configuration is also retained to support easy
backward compatibility for distro vendors. These configurations are
stored in temp files which are further translated using the
hv_set_ifconfig.sh script. This script is implemented by individual
distros based on the network management commands supported.
For example, RHEL's implementation could be found here:
https://gitlab.com/redhat/centos-stream/src/hyperv-daemons/-/blob/c9s/hv_set_ifconfig.sh
Debian's implementation could be found here:
https://github.com/endlessm/linux/blob/master/debian/cloud-tools/hv_set_ifconfig
The next part of this support is to let the Distro vendors consume
these modified implementations to the new configuration format.
Cherry-picked from upstream linux
kernel commit 42999c904612 ("hv/hv_kvp_daemon:Support for keyfile based connection profile")
Tested-on: Rhel9(Hyper-V, Azure)(nm and ifcfg files verified)
Signed-off-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
Reviewed-by: Saurabh Sengar <ssengar@linux.microsoft.com>
Reviewed-by: Ani Sinha <anisinha@redhat.com>
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Link: https://lore.kernel.org/r/1696847920-31125-1-git-send-email-shradhagupta@linux.microsoft.com
patch_name: hpvd-hv-hv_kvp_daemon-Support-for-keyfile-based-connectio.patch
present_in_specfile: true
location_in_specfile: 13
---
hv_kvp_daemon.c | 233 +++++++++++++++++++++++++++++++++++++++------
hv_set_ifconfig.sh | 30 +++++-
2 files changed, 230 insertions(+), 33 deletions(-)
diff --git a/hv_kvp_daemon.c b/hv_kvp_daemon.c
index 27f5e7d..264eeb9 100644
--- a/hv_kvp_daemon.c
+++ b/hv_kvp_daemon.c
@@ -1171,12 +1171,79 @@ static int process_ip_string(FILE *f, char *ip_string, int type)
return 0;
}
+/*
+ * Only IPv4 subnet strings needs to be converted to plen
+ * For IPv6 the subnet is already privided in plen format
+ */
+static int kvp_subnet_to_plen(char *subnet_addr_str)
+{
+ int plen = 0;
+ struct in_addr subnet_addr4;
+
+ /*
+ * Convert subnet address to binary representation
+ */
+ if (inet_pton(AF_INET, subnet_addr_str, &subnet_addr4) == 1) {
+ uint32_t subnet_mask = ntohl(subnet_addr4.s_addr);
+
+ while (subnet_mask & 0x80000000) {
+ plen++;
+ subnet_mask <<= 1;
+ }
+ } else {
+ return -1;
+ }
+
+ return plen;
+}
+
+static int process_ip_string_nm(FILE *f, char *ip_string, char *subnet,
+ int is_ipv6)
+{
+ char addr[INET6_ADDRSTRLEN];
+ char subnet_addr[INET6_ADDRSTRLEN];
+ int error, i = 0;
+ int ip_offset = 0, subnet_offset = 0;
+ int plen;
+
+ memset(addr, 0, sizeof(addr));
+ memset(subnet_addr, 0, sizeof(subnet_addr));
+
+ while (parse_ip_val_buffer(ip_string, &ip_offset, addr,
+ (MAX_IP_ADDR_SIZE * 2)) &&
+ parse_ip_val_buffer(subnet,
+ &subnet_offset,
+ subnet_addr,
+ (MAX_IP_ADDR_SIZE *
+ 2))) {
+ if (!is_ipv6)
+ plen = kvp_subnet_to_plen((char *)subnet_addr);
+ else
+ plen = atoi(subnet_addr);
+
+ if (plen < 0)
+ return plen;
+
+ error = fprintf(f, "address%d=%s/%d\n", ++i, (char *)addr,
+ plen);
+ if (error < 0)
+ return error;
+
+ memset(addr, 0, sizeof(addr));
+ memset(subnet_addr, 0, sizeof(subnet_addr));
+ }
+
+ return 0;
+}
+
static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
{
int error = 0;
- char if_file[PATH_MAX];
- FILE *file;
+ char if_filename[PATH_MAX];
+ char nm_filename[PATH_MAX];
+ FILE *ifcfg_file, *nmfile;
char cmd[PATH_MAX];
+ int is_ipv6 = 0;
char *mac_addr;
int str_len;
@@ -1197,7 +1264,7 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
* in a given distro to configure the interface and so are free
* ignore information that may not be relevant.
*
- * Here is the format of the ip configuration file:
+ * Here is the ifcfg format of the ip configuration file:
*
* HWADDR=macaddr
* DEVICE=interface name
@@ -1220,6 +1287,32 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
* tagged as IPV6_DEFAULTGW and IPV6 NETMASK will be tagged as
* IPV6NETMASK.
*
+ * Here is the keyfile format of the ip configuration file:
+ *
+ * [ethernet]
+ * mac-address=macaddr
+ * [connection]
+ * interface-name=interface name
+ *
+ * [ipv4]
+ * method=<protocol> (where <protocol> is "auto" if DHCP is configured
+ * or "manual" if no boot-time protocol should be used)
+ *
+ * address1=ipaddr1/plen
+ * address2=ipaddr2/plen
+ *
+ * gateway=gateway1;gateway2
+ *
+ * dns=dns1;dns2
+ *
+ * [ipv6]
+ * address1=ipaddr1/plen
+ * address2=ipaddr2/plen
+ *
+ * gateway=gateway1;gateway2
+ *
+ * dns=dns1;dns2
+ *
* The host can specify multiple ipv4 and ipv6 addresses to be
* configured for the interface. Furthermore, the configuration
* needs to be persistent. A subsequent GET call on the interface
@@ -1227,14 +1320,29 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
* call.
*/
- snprintf(if_file, sizeof(if_file), "%s%s%s", KVP_CONFIG_LOC,
- "/ifcfg-", if_name);
+ /*
+ * We are populating both ifcfg and nmconnection files
+ */
+ snprintf(if_filename, sizeof(if_filename), "%s%s%s", KVP_CONFIG_LOC,
+ "/ifcfg-", if_name);
- file = fopen(if_file, "w");
+ ifcfg_file = fopen(if_filename, "w");
- if (file == NULL) {
+ if (!ifcfg_file) {
syslog(LOG_ERR, "Failed to open config file; error: %d %s",
- errno, strerror(errno));
+ errno, strerror(errno));
+ return HV_E_FAIL;
+ }
+
+ snprintf(nm_filename, sizeof(nm_filename), "%s%s%s%s", KVP_CONFIG_LOC,
+ "/", if_name, ".nmconnection");
+
+ nmfile = fopen(nm_filename, "w");
+
+ if (!nmfile) {
+ syslog(LOG_ERR, "Failed to open config file; error: %d %s",
+ errno, strerror(errno));
+ fclose(ifcfg_file);
return HV_E_FAIL;
}
@@ -1248,14 +1356,31 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
goto setval_error;
}
- error = kvp_write_file(file, "HWADDR", "", mac_addr);
- free(mac_addr);
+ error = kvp_write_file(ifcfg_file, "HWADDR", "", mac_addr);
+ if (error < 0)
+ goto setmac_error;
+
+ error = kvp_write_file(ifcfg_file, "DEVICE", "", if_name);
+ if (error < 0)
+ goto setmac_error;
+
+ error = fprintf(nmfile, "\n[connection]\n");
+ if (error < 0)
+ goto setmac_error;
+
+ error = kvp_write_file(nmfile, "interface-name", "", if_name);
if (error)
- goto setval_error;
+ goto setmac_error;
- error = kvp_write_file(file, "DEVICE", "", if_name);
+ error = fprintf(nmfile, "\n[ethernet]\n");
+ if (error < 0)
+ goto setmac_error;
+
+ error = kvp_write_file(nmfile, "mac-address", "", mac_addr);
if (error)
- goto setval_error;
+ goto setmac_error;
+
+ free(mac_addr);
/*
* The dhcp_enabled flag is only for IPv4. In the case the host only
@@ -1263,47 +1388,91 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
* proceed to parse and pass the IPv6 information to the
* disto-specific script hv_set_ifconfig.
*/
+
+ /*
+ * First populate the ifcfg file format
+ */
if (new_val->dhcp_enabled) {
- error = kvp_write_file(file, "BOOTPROTO", "", "dhcp");
+ error = kvp_write_file(ifcfg_file, "BOOTPROTO", "", "dhcp");
if (error)
goto setval_error;
-
} else {
- error = kvp_write_file(file, "BOOTPROTO", "", "none");
+ error = kvp_write_file(ifcfg_file, "BOOTPROTO", "", "none");
if (error)
goto setval_error;
}
- /*
- * Write the configuration for ipaddress, netmask, gateway and
- * name servers.
- */
-
- error = process_ip_string(file, (char *)new_val->ip_addr, IPADDR);
+ error = process_ip_string(ifcfg_file, (char *)new_val->ip_addr,
+ IPADDR);
if (error)
goto setval_error;
- error = process_ip_string(file, (char *)new_val->sub_net, NETMASK);
+ error = process_ip_string(ifcfg_file, (char *)new_val->sub_net,
+ NETMASK);
if (error)
goto setval_error;
- error = process_ip_string(file, (char *)new_val->gate_way, GATEWAY);
+ error = process_ip_string(ifcfg_file, (char *)new_val->gate_way,
+ GATEWAY);
if (error)
goto setval_error;
- error = process_ip_string(file, (char *)new_val->dns_addr, DNS);
+ error = process_ip_string(ifcfg_file, (char *)new_val->dns_addr, DNS);
if (error)
goto setval_error;
- fclose(file);
+ if (new_val->addr_family == ADDR_FAMILY_IPV6) {
+ error = fprintf(nmfile, "\n[ipv6]\n");
+ if (error < 0)
+ goto setval_error;
+ is_ipv6 = 1;
+ } else {
+ error = fprintf(nmfile, "\n[ipv4]\n");
+ if (error < 0)
+ goto setval_error;
+ }
+
+ /*
+ * Now we populate the keyfile format
+ */
+
+ if (new_val->dhcp_enabled) {
+ error = kvp_write_file(nmfile, "method", "", "auto");
+ if (error < 0)
+ goto setval_error;
+ } else {
+ error = kvp_write_file(nmfile, "method", "", "manual");
+ if (error < 0)
+ goto setval_error;
+ }
+
+ /*
+ * Write the configuration for ipaddress, netmask, gateway and
+ * name services
+ */
+ error = process_ip_string_nm(nmfile, (char *)new_val->ip_addr,
+ (char *)new_val->sub_net, is_ipv6);
+ if (error < 0)
+ goto setval_error;
+
+ error = fprintf(nmfile, "gateway=%s\n", (char *)new_val->gate_way);
+ if (error < 0)
+ goto setval_error;
+
+ error = fprintf(nmfile, "dns=%s\n", (char *)new_val->dns_addr);
+ if (error < 0)
+ goto setval_error;
+
+ fclose(nmfile);
+ fclose(ifcfg_file);
/*
* Now that we have populated the configuration file,
* invoke the external script to do its magic.
*/
- str_len = snprintf(cmd, sizeof(cmd), KVP_SCRIPTS_PATH "%s %s",
- "hv_set_ifconfig", if_file);
+ str_len = snprintf(cmd, sizeof(cmd), KVP_SCRIPTS_PATH "%s %s %s",
+ "hv_set_ifconfig", if_filename, nm_filename);
/*
* This is a little overcautious, but it's necessary to suppress some
* false warnings from gcc 8.0.1.
@@ -1316,14 +1485,16 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
if (system(cmd)) {
syslog(LOG_ERR, "Failed to execute cmd '%s'; error: %d %s",
- cmd, errno, strerror(errno));
+ cmd, errno, strerror(errno));
return HV_E_FAIL;
}
return 0;
-
+setmac_error:
+ free(mac_addr);
setval_error:
syslog(LOG_ERR, "Failed to write config file");
- fclose(file);
+ fclose(ifcfg_file);
+ fclose(nmfile);
return error;
}
diff --git a/hv_set_ifconfig.sh b/hv_set_ifconfig.sh
index fe7fccf..35aae6f 100644
--- a/hv_set_ifconfig.sh
+++ b/hv_set_ifconfig.sh
@@ -18,12 +18,12 @@
#
# This example script is based on a RHEL environment.
#
-# Here is the format of the ip configuration file:
+# Here is the ifcfg format of the ip configuration file:
#
# HWADDR=macaddr
# DEVICE=interface name
# BOOTPROTO=<protocol> (where <protocol> is "dhcp" if DHCP is configured
-# or "none" if no boot-time protocol should be used)
+# or "none" if no boot-time protocol should be used)
#
# IPADDR0=ipaddr1
# IPADDR1=ipaddr2
@@ -41,6 +41,32 @@
# tagged as IPV6_DEFAULTGW and IPV6 NETMASK will be tagged as
# IPV6NETMASK.
#
+# Here is the keyfile format of the ip configuration file:
+#
+# [ethernet]
+# mac-address=macaddr
+# [connection]
+# interface-name=interface name
+#
+# [ipv4]
+# method=<protocol> (where <protocol> is "auto" if DHCP is configured
+# or "manual" if no boot-time protocol should be used)
+#
+# address1=ipaddr1/plen
+# address=ipaddr2/plen
+#
+# gateway=gateway1;gateway2
+#
+# dns=dns1;
+#
+# [ipv6]
+# address1=ipaddr1/plen
+# address2=ipaddr1/plen
+#
+# gateway=gateway1;gateway2
+#
+# dns=dns1;dns2
+#
# The host can specify multiple ipv4 and ipv6 addresses to be
# configured for the interface. Furthermore, the configuration
# needs to be persistent. A subsequent GET call on the interface
--
2.39.3

@ -1,19 +1,22 @@
From ac2132ceaeb611c89eacb468a66f1815ee6fe806 Mon Sep 17 00:00:00 2001
From 5b1094b6e8d7b5314ff32cef741e22bf2904d81f Mon Sep 17 00:00:00 2001
From: Till Maas <timaas@redhat.com>
Date: Mon, 13 Dec 2021 16:08:42 +0000
Subject: [PATCH 1/2] hv_set_ifconfig.sh: Use nmcli commands
Subject: [PATCH 04/14] hv_set_ifconfig.sh: Use nmcli commands
RH-Author: Till Maas <None>
RH-MergeRequest: 2: hv_set_ifconfig.sh: Use nmcli commands
RH-Commit: [1/2] fbb64255b1d96babd362391d53529cef0e449296 (timaas/hyperv-daemons)
RH-Bugzilla: 2026371
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-MergeRequest: 9: Synchronize RHEL 9 changes to RHEL 10
RH-Jira: RHEL-40107 RHEL-40679
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Commit: [4/14] 657c30ec2f7f3cf90cd0950e45b2441280ef2581 (mrezanin/centos-git-hyperv-daemons)
Instead of using deprecated ifup/ifdown commands, use nmcli commands.
Taking the connection down is not necessary with NM, so don't do it.
Resolves: #2026371
patch_name: hpvd-hv_set_ifconfig.sh-Use-nmcli-commands.patch
present_in_specfile: true
location_in_specfile: 7
---
hv_set_ifconfig.sh | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
@ -34,5 +37,5 @@ index 3dd064c..5a64efe 100644
+nmcli connection load "/etc/sysconfig/network-scripts/$1"
+nmcli connection up filename "/etc/sysconfig/network-scripts/$1"
--
2.27.0
2.39.3

@ -1,17 +1,14 @@
From 74730b2187402e29c3c6b4074eae945b7614d1dc Mon Sep 17 00:00:00 2001
From 039cd98452fcf585533455c28200d438cda8ed7a Mon Sep 17 00:00:00 2001
From: Mohammed Gamal <mgamal@redhat.com>
Date: Tue, 8 Nov 2022 16:20:17 +0100
Subject: [PATCH 1/3] redhat: hv_set_if_config: Workaround for gateway
Subject: [PATCH 06/14] redhat: hv_set_if_config: Workaround for gateway
numbering in NetworkManager
RH-Author: Mohamed Gamal Morsy <mmorsy@redhat.com>
RH-MergeRequest: 4: redhat: hv_set_if_config: Workaround for gateway numbering in NetworkManager
RH-Bugzilla: 2122115
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Cathy Avery <cavery@redhat.com>
RH-Commit: [1/1] 5fef25a723094255f3cb25beaa4e18f1ec9d339f
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2122115
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-MergeRequest: 9: Synchronize RHEL 9 changes to RHEL 10
RH-Jira: RHEL-40107 RHEL-40679
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Commit: [6/14] 984b946aea905b94672aead098e73368e6c65fc7 (mrezanin/centos-git-hyperv-daemons)
Unlike older sysconfig scripts, NetworkManager expects GATEWAYx=ipaddr for all values of x.
So the first gateway is GATEWAY0 instead of GATEWAY. Other values should remain unchanged.
@ -22,6 +19,10 @@ That can be done eitter by changing hypervkvpd code to do that or to let the scr
ifcfg files and generate corresponding NetworkManager keyfiles
Signed-off-by: Mohammed Gamal <mgamal@redhat.com>
patch_name: hpvd-redhat-hv_set_if_config-Workaround-for-gateway-numbe.patch
present_in_specfile: true
location_in_specfile: 9
---
hv_set_ifconfig.sh | 4 ++++
1 file changed, 4 insertions(+)
@ -42,5 +43,5 @@ index 146829b..fe7fccf 100644
cp $1 /etc/sysconfig/network-scripts/
--
2.31.1
2.39.3

@ -1,16 +1,13 @@
From 18888d66ca55ebefbf36dc74ab25c3958d56789b Mon Sep 17 00:00:00 2001
From b4af57850a0f8171116eacb6e8a565ef009e9c4b Mon Sep 17 00:00:00 2001
From: Mohammed Gamal <mgamal@redhat.com>
Date: Thu, 17 Nov 2022 18:56:20 +0100
Subject: [PATCH 2/3] tools: hv: Remove an extraneous "the"
Subject: [PATCH 07/14] tools: hv: Remove an extraneous "the"
RH-Author: Mohamed Gamal Morsy <mmorsy@redhat.com>
RH-MergeRequest: 5: Update hyperv-daemons for RHEL-9.2
RH-Bugzilla: 2139457
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/2] 53bf20c6a219a20e7a2ae3986a9b2ed43ac4faac
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2139457
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-MergeRequest: 9: Synchronize RHEL 9 changes to RHEL 10
RH-Jira: RHEL-40107 RHEL-40679
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Commit: [7/14] 55fe13a9967894578468229dc925fb106bce7355 (mrezanin/centos-git-hyperv-daemons)
commit f15f39fabed2248311607445ddfa6dba63abebb9
Author: Jason Wang <wangborong@cdjrlc.com>
@ -25,12 +22,16 @@ Date: Thu Aug 11 21:34:33 2022 +0800
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Signed-off-by: Mohammed Gamal <mgamal@redhat.com>
patch_name: hpvd-tools-hv-Remove-an-extraneous-the.patch
present_in_specfile: true
location_in_specfile: 10
---
hv_kvp_daemon.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hv_kvp_daemon.c b/hv_kvp_daemon.c
index c06c94d..5f98bee 100644
index 1e6fd6c..c97c12e 100644
--- a/hv_kvp_daemon.c
+++ b/hv_kvp_daemon.c
@@ -44,7 +44,7 @@
@ -43,5 +44,5 @@ index c06c94d..5f98bee 100644
* fills in the value corresponding to the specified key. We overload the
* sequence field in the cn_msg header to define our KVP message types.
--
2.31.1
2.39.3

@ -1,16 +1,13 @@
From 07081e4a9622c042dec1e3c7ffd47722a6dc0337 Mon Sep 17 00:00:00 2001
From 1a616ef74b66a45c1e16ec12e46fabfc03613668 Mon Sep 17 00:00:00 2001
From: Mohammed Gamal <mgamal@redhat.com>
Date: Thu, 17 Nov 2022 18:58:31 +0100
Subject: [PATCH 3/3] tools: hv: kvp: remove unnecessary (void*) conversions
Subject: [PATCH 08/14] tools: hv: kvp: remove unnecessary (void*) conversions
RH-Author: Mohamed Gamal Morsy <mmorsy@redhat.com>
RH-MergeRequest: 5: Update hyperv-daemons for RHEL-9.2
RH-Bugzilla: 2139457
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [2/2] d3fe2884e899eab164e8b42398db72618b05ec71
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2139457
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-MergeRequest: 9: Synchronize RHEL 9 changes to RHEL 10
RH-Jira: RHEL-40107 RHEL-40679
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Commit: [8/14] 16a5e8f5c4799f6777600cd62b4621e450638f22 (mrezanin/centos-git-hyperv-daemons)
commit 2258954234db7530e9d86bb32cd6ad54485ff926
Author: Zhou jie <zhoujie@nfschina.com>
@ -26,12 +23,16 @@ Date: Tue Aug 23 11:45:52 2022 +0800
Signed-off-by: Wei Liu <wei.liu@kernel.org>
Signed-off-by: Mohammed Gamal <mgamal@redhat.com>
patch_name: hpvd-tools-hv-kvp-remove-unnecessary-void-conversions.patch
present_in_specfile: true
location_in_specfile: 11
---
hv_kvp_daemon.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hv_kvp_daemon.c b/hv_kvp_daemon.c
index 5f98bee..2ad9af3 100644
index c97c12e..27f5e7d 100644
--- a/hv_kvp_daemon.c
+++ b/hv_kvp_daemon.c
@@ -772,11 +772,11 @@ static int kvp_process_ip_address(void *addrp,
@ -49,5 +50,5 @@ index 5f98bee..2ad9af3 100644
addr_length = INET6_ADDRSTRLEN;
}
--
2.31.1
2.39.3

@ -1,14 +1,14 @@
From 21261cb75d523dd3ac815524e66f53694c1a3c2a Mon Sep 17 00:00:00 2001
From 520bfb6b8bc7cedc2dcb602a708c1357faf638b8 Mon Sep 17 00:00:00 2001
From: Ani Sinha <anisinha@redhat.com>
Date: Wed, 5 Jul 2023 18:44:34 +0530
Subject: [PATCH] vmbus_testing: fix wrong python syntax for integer value
comparison
Subject: [PATCH 09/14] vmbus_testing: fix wrong python syntax for integer
value comparison
RH-Author: Ani Sinha <None>
RH-MergeRequest: 6: vmbus_testing: fix wrong python syntax for interger value comparison
RH-Bugzilla: 2218931
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Commit: [1/1] 2887e0ad51a16a499ebdeac29f3086c8be481e0c (anisinha/centos-hyperv-daemons)
RH-Author: Miroslav Rezanina <mrezanin@redhat.com>
RH-MergeRequest: 9: Synchronize RHEL 9 changes to RHEL 10
RH-Jira: RHEL-40107 RHEL-40679
RH-Acked-by: Ani Sinha <anisinha@redhat.com>
RH-Commit: [9/14] 261dfeef254265a966e7175766f366eaed782454 (mrezanin/centos-git-hyperv-daemons)
It is incorrect in python to compare integer values using the "is" keyword. The
"is" keyword in python is used to compare references to two objects, not their
@ -19,8 +19,11 @@ Fix this in the code and suppress the following warning:
/usr/sbin/vmbus_testing:167: SyntaxWarning: "is" with a literal. Did you mean "=="?
RHBZ: 2218931
Signed-off-by: Ani Sinha <anisinha@redhat.com>
patch_name: hpvd-vmbus_testing-fix-wrong-python-syntax-for-integer-va.patch
present_in_specfile: true
location_in_specfile: 12
---
vmbus_testing | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

@ -1,239 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* An implementation of host to guest copy functionality for Linux.
*
* Copyright (C) 2014, Microsoft, Inc.
*
* Author : K. Y. Srinivasan <kys@microsoft.com>
*/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <linux/hyperv.h>
#include <linux/limits.h>
#include <syslog.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <getopt.h>
static int target_fd;
static char target_fname[PATH_MAX];
static unsigned long long filesize;
static int hv_start_fcopy(struct hv_start_fcopy *smsg)
{
int error = HV_E_FAIL;
char *q, *p;
filesize = 0;
p = (char *)smsg->path_name;
snprintf(target_fname, sizeof(target_fname), "%s/%s",
(char *)smsg->path_name, (char *)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)) {
error = HV_ERROR_ALREADY_EXISTS;
goto done;
}
}
target_fd = open(target_fname,
O_RDWR | O_CREAT | O_TRUNC | 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;
int ret = 0;
bytes_written = pwrite(target_fd, cpmsg->data, cpmsg->size,
cpmsg->offset);
filesize += cpmsg->size;
if (bytes_written != cpmsg->size) {
switch (errno) {
case ENOSPC:
ret = HV_ERROR_DISK_FULL;
break;
default:
ret = HV_E_FAIL;
break;
}
syslog(LOG_ERR, "pwrite failed to write %llu bytes: %ld (%s)",
filesize, (long)bytes_written, strerror(errno));
}
return ret;
}
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;
}
void print_usage(char *argv[])
{
fprintf(stderr, "Usage: %s [options]\n"
"Options are:\n"
" -n, --no-daemon stay in foreground, don't daemonize\n"
" -h, --help print this help\n", argv[0]);
}
int main(int argc, char *argv[])
{
int fcopy_fd;
int error;
int daemonize = 1, long_index = 0, opt;
int version = FCOPY_CURRENT_VERSION;
union {
struct hv_fcopy_hdr hdr;
struct hv_start_fcopy start;
struct hv_do_fcopy copy;
__u32 kernel_modver;
} buffer = { };
int in_handshake = 1;
static struct option long_options[] = {
{"help", no_argument, 0, 'h' },
{"no-daemon", no_argument, 0, 'n' },
{0, 0, 0, 0 }
};
while ((opt = getopt_long(argc, argv, "hn", long_options,
&long_index)) != -1) {
switch (opt) {
case 'n':
daemonize = 0;
break;
case 'h':
default:
print_usage(argv);
exit(EXIT_FAILURE);
}
}
if (daemonize && daemon(1, 0)) {
syslog(LOG_ERR, "daemon() failed; error: %s", strerror(errno));
exit(EXIT_FAILURE);
}
openlog("HV_FCOPY", 0, LOG_USER);
syslog(LOG_INFO, "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.
*/
ssize_t len;
len = pread(fcopy_fd, &buffer, sizeof(buffer), 0);
if (len < 0) {
syslog(LOG_ERR, "pread failed: %s", strerror(errno));
exit(EXIT_FAILURE);
}
if (in_handshake) {
if (len != sizeof(buffer.kernel_modver)) {
syslog(LOG_ERR, "invalid version negotiation");
exit(EXIT_FAILURE);
}
in_handshake = 0;
syslog(LOG_INFO, "kernel module version: %u",
buffer.kernel_modver);
continue;
}
switch (buffer.hdr.operation) {
case START_FILE_COPY:
error = hv_start_fcopy(&buffer.start);
break;
case WRITE_TO_FILE:
error = hv_copy_data(&buffer.copy);
break;
case COMPLETE_FCOPY:
error = hv_copy_finished();
break;
case CANCEL_FCOPY:
error = hv_copy_cancel();
break;
default:
error = HV_E_FAIL;
syslog(LOG_ERR, "Unknown operation: %d",
buffer.hdr.operation);
}
if (pwrite(fcopy_fd, &error, sizeof(int), 0) != sizeof(int)) {
syslog(LOG_ERR, "pwrite failed: %s", strerror(errno));
exit(EXIT_FAILURE);
}
}
}

@ -0,0 +1,490 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* An implementation of host to guest copy functionality for Linux.
*
* Copyright (C) 2023, Microsoft, Inc.
*
* Author : K. Y. Srinivasan <kys@microsoft.com>
* Author : Saurabh Sengar <ssengar@microsoft.com>
*
*/
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <locale.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <wchar.h>
#include <sys/stat.h>
#include <linux/hyperv.h>
#include <linux/limits.h>
#include "vmbus_bufring.h"
#define ICMSGTYPE_NEGOTIATE 0
#define ICMSGTYPE_FCOPY 7
#define WIN8_SRV_MAJOR 1
#define WIN8_SRV_MINOR 1
#define WIN8_SRV_VERSION (WIN8_SRV_MAJOR << 16 | WIN8_SRV_MINOR)
#define MAX_FOLDER_NAME 15
#define MAX_PATH_LEN 15
#define FCOPY_UIO "/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/uio"
#define FCOPY_VER_COUNT 1
static const int fcopy_versions[] = {
WIN8_SRV_VERSION
};
#define FW_VER_COUNT 1
static const int fw_versions[] = {
UTIL_FW_VERSION
};
#define HV_RING_SIZE 0x4000 /* 16KB ring buffer size */
unsigned char desc[HV_RING_SIZE];
static int target_fd;
static char target_fname[PATH_MAX];
static unsigned long long filesize;
static int hv_fcopy_create_file(char *file_name, char *path_name, __u32 flags)
{
int error = HV_E_FAIL;
char *q, *p;
filesize = 0;
p = path_name;
snprintf(target_fname, sizeof(target_fname), "%s/%s",
path_name, file_name);
/*
* 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(path_name, F_OK)) {
if (flags & CREATE_PATH) {
if (mkdir(path_name, 0755)) {
syslog(LOG_ERR, "Failed to create %s",
path_name);
goto done;
}
} else {
syslog(LOG_ERR, "Invalid path: %s", path_name);
goto done;
}
}
p = q + 1;
*q = '/';
}
if (!access(target_fname, F_OK)) {
syslog(LOG_INFO, "File: %s exists", target_fname);
if (!(flags & OVER_WRITE)) {
error = HV_ERROR_ALREADY_EXISTS;
goto done;
}
}
target_fd = open(target_fname,
O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0744);
if (target_fd == -1) {
syslog(LOG_INFO, "Open Failed: %s", strerror(errno));
goto done;
}
error = 0;
done:
if (error)
target_fname[0] = '\0';
return error;
}
/* copy the data into the file */
static int hv_copy_data(struct hv_do_fcopy *cpmsg)
{
ssize_t len;
int ret = 0;
len = pwrite(target_fd, cpmsg->data, cpmsg->size, cpmsg->offset);
filesize += cpmsg->size;
if (len != cpmsg->size) {
switch (errno) {
case ENOSPC:
ret = HV_ERROR_DISK_FULL;
break;
default:
ret = HV_E_FAIL;
break;
}
syslog(LOG_ERR, "pwrite failed to write %llu bytes: %ld (%s)",
filesize, (long)len, strerror(errno));
}
return ret;
}
static int hv_copy_finished(void)
{
close(target_fd);
target_fname[0] = '\0';
return 0;
}
static void print_usage(char *argv[])
{
fprintf(stderr, "Usage: %s [options]\n"
"Options are:\n"
" -n, --no-daemon stay in foreground, don't daemonize\n"
" -h, --help print this help\n", argv[0]);
}
static bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, unsigned char *buf,
unsigned int buflen, const int *fw_version, int fw_vercnt,
const int *srv_version, int srv_vercnt,
int *nego_fw_version, int *nego_srv_version)
{
int icframe_major, icframe_minor;
int icmsg_major, icmsg_minor;
int fw_major, fw_minor;
int srv_major, srv_minor;
int i, j;
bool found_match = false;
struct icmsg_negotiate *negop;
/* Check that there's enough space for icframe_vercnt, icmsg_vercnt */
if (buflen < ICMSG_HDR + offsetof(struct icmsg_negotiate, reserved)) {
syslog(LOG_ERR, "Invalid icmsg negotiate");
return false;
}
icmsghdrp->icmsgsize = 0x10;
negop = (struct icmsg_negotiate *)&buf[ICMSG_HDR];
icframe_major = negop->icframe_vercnt;
icframe_minor = 0;
icmsg_major = negop->icmsg_vercnt;
icmsg_minor = 0;
/* Validate negop packet */
if (icframe_major > IC_VERSION_NEGOTIATION_MAX_VER_COUNT ||
icmsg_major > IC_VERSION_NEGOTIATION_MAX_VER_COUNT ||
ICMSG_NEGOTIATE_PKT_SIZE(icframe_major, icmsg_major) > buflen) {
syslog(LOG_ERR, "Invalid icmsg negotiate - icframe_major: %u, icmsg_major: %u\n",
icframe_major, icmsg_major);
goto fw_error;
}
/*
* Select the framework version number we will
* support.
*/
for (i = 0; i < fw_vercnt; i++) {
fw_major = (fw_version[i] >> 16);
fw_minor = (fw_version[i] & 0xFFFF);
for (j = 0; j < negop->icframe_vercnt; j++) {
if (negop->icversion_data[j].major == fw_major &&
negop->icversion_data[j].minor == fw_minor) {
icframe_major = negop->icversion_data[j].major;
icframe_minor = negop->icversion_data[j].minor;
found_match = true;
break;
}
}
if (found_match)
break;
}
if (!found_match)
goto fw_error;
found_match = false;
for (i = 0; i < srv_vercnt; i++) {
srv_major = (srv_version[i] >> 16);
srv_minor = (srv_version[i] & 0xFFFF);
for (j = negop->icframe_vercnt;
(j < negop->icframe_vercnt + negop->icmsg_vercnt);
j++) {
if (negop->icversion_data[j].major == srv_major &&
negop->icversion_data[j].minor == srv_minor) {
icmsg_major = negop->icversion_data[j].major;
icmsg_minor = negop->icversion_data[j].minor;
found_match = true;
break;
}
}
if (found_match)
break;
}
/*
* Respond with the framework and service
* version numbers we can support.
*/
fw_error:
if (!found_match) {
negop->icframe_vercnt = 0;
negop->icmsg_vercnt = 0;
} else {
negop->icframe_vercnt = 1;
negop->icmsg_vercnt = 1;
}
if (nego_fw_version)
*nego_fw_version = (icframe_major << 16) | icframe_minor;
if (nego_srv_version)
*nego_srv_version = (icmsg_major << 16) | icmsg_minor;
negop->icversion_data[0].major = icframe_major;
negop->icversion_data[0].minor = icframe_minor;
negop->icversion_data[1].major = icmsg_major;
negop->icversion_data[1].minor = icmsg_minor;
return found_match;
}
static void wcstoutf8(char *dest, const __u16 *src, size_t dest_size)
{
size_t len = 0;
while (len < dest_size) {
if (src[len] < 0x80)
dest[len++] = (char)(*src++);
else
dest[len++] = 'X';
}
dest[len] = '\0';
}
static int hv_fcopy_start(struct hv_start_fcopy *smsg_in)
{
setlocale(LC_ALL, "en_US.utf8");
size_t file_size, path_size;
char *file_name, *path_name;
char *in_file_name = (char *)smsg_in->file_name;
char *in_path_name = (char *)smsg_in->path_name;
file_size = wcstombs(NULL, (const wchar_t *restrict)in_file_name, 0) + 1;
path_size = wcstombs(NULL, (const wchar_t *restrict)in_path_name, 0) + 1;
file_name = (char *)malloc(file_size * sizeof(char));
path_name = (char *)malloc(path_size * sizeof(char));
wcstoutf8(file_name, (__u16 *)in_file_name, file_size);
wcstoutf8(path_name, (__u16 *)in_path_name, path_size);
return hv_fcopy_create_file(file_name, path_name, smsg_in->copy_flags);
}
static int hv_fcopy_send_data(struct hv_fcopy_hdr *fcopy_msg, int recvlen)
{
int operation = fcopy_msg->operation;
/*
* The strings sent from the host are encoded in
* utf16; convert it to utf8 strings.
* The host assures us that the utf16 strings will not exceed
* the max lengths specified. We will however, reserve room
* for the string terminating character - in the utf16s_utf8s()
* function we limit the size of the buffer where the converted
* string is placed to W_MAX_PATH -1 to guarantee
* that the strings can be properly terminated!
*/
switch (operation) {
case START_FILE_COPY:
return hv_fcopy_start((struct hv_start_fcopy *)fcopy_msg);
case WRITE_TO_FILE:
return hv_copy_data((struct hv_do_fcopy *)fcopy_msg);
case COMPLETE_FCOPY:
return hv_copy_finished();
}
return HV_E_FAIL;
}
/* process the packet recv from host */
static int fcopy_pkt_process(struct vmbus_br *txbr)
{
int ret, offset, pktlen;
int fcopy_srv_version;
const struct vmbus_chanpkt_hdr *pkt;
struct hv_fcopy_hdr *fcopy_msg;
struct icmsg_hdr *icmsghdr;
pkt = (const struct vmbus_chanpkt_hdr *)desc;
offset = pkt->hlen << 3;
pktlen = (pkt->tlen << 3) - offset;
icmsghdr = (struct icmsg_hdr *)&desc[offset + sizeof(struct vmbuspipe_hdr)];
icmsghdr->status = HV_E_FAIL;
if (icmsghdr->icmsgtype == ICMSGTYPE_NEGOTIATE) {
if (vmbus_prep_negotiate_resp(icmsghdr, desc + offset, pktlen, fw_versions,
FW_VER_COUNT, fcopy_versions, FCOPY_VER_COUNT,
NULL, &fcopy_srv_version)) {
syslog(LOG_INFO, "FCopy IC version %d.%d",
fcopy_srv_version >> 16, fcopy_srv_version & 0xFFFF);
icmsghdr->status = 0;
}
} else if (icmsghdr->icmsgtype == ICMSGTYPE_FCOPY) {
/* Ensure recvlen is big enough to contain hv_fcopy_hdr */
if (pktlen < ICMSG_HDR + sizeof(struct hv_fcopy_hdr)) {
syslog(LOG_ERR, "Invalid Fcopy hdr. Packet length too small: %u",
pktlen);
return -ENOBUFS;
}
fcopy_msg = (struct hv_fcopy_hdr *)&desc[offset + ICMSG_HDR];
icmsghdr->status = hv_fcopy_send_data(fcopy_msg, pktlen);
}
icmsghdr->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE;
ret = rte_vmbus_chan_send(txbr, 0x6, desc + offset, pktlen, 0);
if (ret) {
syslog(LOG_ERR, "Write to ringbuffer failed err: %d", ret);
return ret;
}
return 0;
}
static void fcopy_get_first_folder(char *path, char *chan_no)
{
DIR *dir = opendir(path);
struct dirent *entry;
if (!dir) {
syslog(LOG_ERR, "Failed to open directory (errno=%s).\n", strerror(errno));
return;
}
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR && strcmp(entry->d_name, ".") != 0 &&
strcmp(entry->d_name, "..") != 0) {
strcpy(chan_no, entry->d_name);
break;
}
}
closedir(dir);
}
int main(int argc, char *argv[])
{
int fcopy_fd = -1, tmp = 1;
int daemonize = 1, long_index = 0, opt, ret = -EINVAL;
struct vmbus_br txbr, rxbr;
void *ring;
uint32_t len = HV_RING_SIZE;
char uio_name[MAX_FOLDER_NAME] = {0};
char uio_dev_path[MAX_PATH_LEN] = {0};
static struct option long_options[] = {
{"help", no_argument, 0, 'h' },
{"no-daemon", no_argument, 0, 'n' },
{0, 0, 0, 0 }
};
while ((opt = getopt_long(argc, argv, "hn", long_options,
&long_index)) != -1) {
switch (opt) {
case 'n':
daemonize = 0;
break;
case 'h':
default:
print_usage(argv);
goto exit;
}
}
if (daemonize && daemon(1, 0)) {
syslog(LOG_ERR, "daemon() failed; error: %s", strerror(errno));
goto exit;
}
openlog("HV_UIO_FCOPY", 0, LOG_USER);
syslog(LOG_INFO, "starting; pid is:%d", getpid());
fcopy_get_first_folder(FCOPY_UIO, uio_name);
snprintf(uio_dev_path, sizeof(uio_dev_path), "/dev/%s", uio_name);
fcopy_fd = open(uio_dev_path, O_RDWR);
if (fcopy_fd < 0) {
syslog(LOG_ERR, "open %s failed; error: %d %s",
uio_dev_path, errno, strerror(errno));
ret = fcopy_fd;
goto exit;
}
ring = vmbus_uio_map(&fcopy_fd, HV_RING_SIZE);
if (!ring) {
ret = errno;
syslog(LOG_ERR, "mmap ringbuffer failed; error: %d %s", ret, strerror(ret));
goto close;
}
vmbus_br_setup(&txbr, ring, HV_RING_SIZE);
vmbus_br_setup(&rxbr, (char *)ring + HV_RING_SIZE, HV_RING_SIZE);
rxbr.vbr->imask = 0;
while (1) {
/*
* In this loop we process fcopy messages after the
* handshake is complete.
*/
ret = pread(fcopy_fd, &tmp, sizeof(int), 0);
if (ret < 0) {
syslog(LOG_ERR, "pread failed: %s", strerror(errno));
continue;
}
len = HV_RING_SIZE;
ret = rte_vmbus_chan_recv_raw(&rxbr, desc, &len);
if (unlikely(ret <= 0)) {
/* This indicates a failure to communicate (or worse) */
syslog(LOG_ERR, "VMBus channel recv error: %d", ret);
} else {
ret = fcopy_pkt_process(&txbr);
if (ret < 0)
goto close;
/* Signal host */
if ((write(fcopy_fd, &tmp, sizeof(int))) != sizeof(int)) {
ret = errno;
syslog(LOG_ERR, "Signal to host failed: %s\n", strerror(ret));
goto close;
}
}
}
close:
close(fcopy_fd);
exit:
return ret;
}

@ -13,7 +13,7 @@
# the script prints the string "Disabled" to stdout.
#
# Each Distro is expected to implement this script in a distro specific
# fashion. For instance on Distros that ship with Network Manager enabled,
# fashion. For instance, on Distros that ship with Network Manager enabled,
# this script can be based on the Network Manager APIs for retrieving DHCP
# information.

@ -76,7 +76,7 @@ enum {
DNS
};
static int in_hand_shake = 1;
static int in_hand_shake;
static char *os_name = "";
static char *os_major = "";
@ -437,7 +437,7 @@ void kvp_get_os_info(void)
/*
* Parse the /etc/os-release file if present:
* http://www.freedesktop.org/software/systemd/man/os-release.html
* https://www.freedesktop.org/software/systemd/man/os-release.html
*/
file = fopen("/etc/os-release", "r");
if (file != NULL) {
@ -1360,7 +1360,7 @@ void print_usage(char *argv[])
int main(int argc, char *argv[])
{
int kvp_fd, len;
int kvp_fd = -1, len;
int error;
struct pollfd pfd;
char *p;
@ -1400,14 +1400,6 @@ int main(int argc, char *argv[])
openlog("KVP", 0, LOG_USER);
syslog(LOG_INFO, "KVP starting; pid is:%d", getpid());
kvp_fd = open("/dev/vmbus/hv_kvp", O_RDWR | O_CLOEXEC);
if (kvp_fd < 0) {
syslog(LOG_ERR, "open /dev/vmbus/hv_kvp failed; error: %d %s",
errno, strerror(errno));
exit(EXIT_FAILURE);
}
/*
* Retrieve OS release information.
*/
@ -1423,6 +1415,18 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
reopen_kvp_fd:
if (kvp_fd != -1)
close(kvp_fd);
in_hand_shake = 1;
kvp_fd = open("/dev/vmbus/hv_kvp", O_RDWR | O_CLOEXEC);
if (kvp_fd < 0) {
syslog(LOG_ERR, "open /dev/vmbus/hv_kvp failed; error: %d %s",
errno, strerror(errno));
exit(EXIT_FAILURE);
}
/*
* Register ourselves with the kernel.
*/
@ -1456,9 +1460,7 @@ int main(int argc, char *argv[])
if (len != sizeof(struct hv_kvp_msg)) {
syslog(LOG_ERR, "read failed; error:%d %s",
errno, strerror(errno));
close(kvp_fd);
return EXIT_FAILURE;
goto reopen_kvp_fd;
}
/*
@ -1617,13 +1619,17 @@ int main(int argc, char *argv[])
break;
}
/* Send the value back to the kernel. */
/*
* Send the value back to the kernel. Note: the write() may
* return an error due to hibernation; we can ignore the error
* by resetting the dev file, i.e. closing and re-opening it.
*/
kvp_done:
len = write(kvp_fd, hv_msg, sizeof(struct hv_kvp_msg));
if (len != sizeof(struct hv_kvp_msg)) {
syslog(LOG_ERR, "write failed; error: %d %s", errno,
strerror(errno));
exit(EXIT_FAILURE);
goto reopen_kvp_fd;
}
}

@ -12,7 +12,7 @@
# be used to configure the interface.
#
# Each Distro is expected to implement this script in a distro specific
# fashion. For instance on Distros that ship with Network Manager enabled,
# fashion. For instance, on Distros that ship with Network Manager enabled,
# this script can be based on the Network Manager APIs for configuring the
# interface.
#

@ -28,6 +28,8 @@
#include <stdbool.h>
#include <dirent.h>
static bool fs_frozen;
/* Don't use syslog() in the function since that can cause write to disk */
static int vss_do_freeze(char *dir, unsigned int cmd)
{
@ -155,18 +157,27 @@ static int vss_operate(int operation)
continue;
}
error |= vss_do_freeze(ent->mnt_dir, cmd);
if (error && operation == VSS_OP_FREEZE)
goto err;
if (operation == VSS_OP_FREEZE) {
if (error)
goto err;
fs_frozen = true;
}
}
endmntent(mounts);
if (root_seen) {
error |= vss_do_freeze("/", cmd);
if (error && operation == VSS_OP_FREEZE)
goto err;
if (operation == VSS_OP_FREEZE) {
if (error)
goto err;
fs_frozen = true;
}
}
if (operation == VSS_OP_THAW && !error)
fs_frozen = false;
goto out;
err:
save_errno = errno;
@ -175,6 +186,7 @@ err:
endmntent(mounts);
}
vss_operate(VSS_OP_THAW);
fs_frozen = false;
/* Call syslog after we thaw all filesystems */
if (ent)
syslog(LOG_ERR, "FREEZE of %s failed; error:%d %s",
@ -196,13 +208,13 @@ void print_usage(char *argv[])
int main(int argc, char *argv[])
{
int vss_fd, len;
int vss_fd = -1, len;
int error;
struct pollfd pfd;
int op;
struct hv_vss_msg vss_msg[1];
int daemonize = 1, long_index = 0, opt;
int in_handshake = 1;
int in_handshake;
__u32 kernel_modver;
static struct option long_options[] = {
@ -232,6 +244,18 @@ int main(int argc, char *argv[])
openlog("Hyper-V VSS", 0, LOG_USER);
syslog(LOG_INFO, "VSS starting; pid is:%d", getpid());
reopen_vss_fd:
if (vss_fd != -1)
close(vss_fd);
if (fs_frozen) {
if (vss_operate(VSS_OP_THAW) || fs_frozen) {
syslog(LOG_ERR, "failed to thaw file system: err=%d",
errno);
exit(EXIT_FAILURE);
}
}
in_handshake = 1;
vss_fd = open("/dev/vmbus/hv_vss", O_RDWR);
if (vss_fd < 0) {
syslog(LOG_ERR, "open /dev/vmbus/hv_vss failed; error: %d %s",
@ -284,8 +308,7 @@ int main(int argc, char *argv[])
if (len != sizeof(struct hv_vss_msg)) {
syslog(LOG_ERR, "read failed; error:%d %s",
errno, strerror(errno));
close(vss_fd);
return EXIT_FAILURE;
goto reopen_vss_fd;
}
op = vss_msg->vss_hdr.operation;
@ -312,14 +335,18 @@ int main(int argc, char *argv[])
default:
syslog(LOG_ERR, "Illegal op:%d\n", op);
}
/*
* The write() may return an error due to the faked VSS_OP_THAW
* message upon hibernation. Ignore the error by resetting the
* dev file, i.e. closing and re-opening it.
*/
vss_msg->error = error;
len = write(vss_fd, vss_msg, sizeof(struct hv_vss_msg));
if (len != sizeof(struct hv_vss_msg)) {
syslog(LOG_ERR, "write failed; error: %d %s", errno,
strerror(errno));
if (op == VSS_OP_FREEZE)
vss_operate(VSS_OP_THAW);
goto reopen_vss_fd;
}
}

@ -1 +0,0 @@
SUBSYSTEM=="misc", KERNEL=="vmbus/hv_fcopy", TAG+="systemd", ENV{SYSTEMD_WANTS}+="hypervfcopyd.service"

@ -1,7 +1,11 @@
[Unit]
Description=Hyper-V FCOPY daemon
BindsTo=sys-devices-virtual-misc-vmbus\x21hv_fcopy.device
Description=Hyper-V FCOPY UIO daemon
ConditionPathExists=/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/
IgnoreOnIsolate=1
[Service]
ExecStart=/usr/sbin/hypervfcopyd -n
ExecStartPre=/bin/sh -c '[ ! -d /sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/uio ] && modprobe uio_hv_generic && echo 34d14be3-dee4-41c8-9ae7-6b174977c192 > /sys/bus/vmbus/drivers/uio_hv_generic/new_id ||:'
ExecStart=/usr/sbin/hv_fcopy_uio_daemon -n
[Install]
WantedBy=multi-user.target

@ -1,5 +1,6 @@
[Unit]
Description=Hyper-V VSS daemon
ConditionVirtualization=microsoft
BindsTo=sys-devices-virtual-misc-vmbus\x21hv_vss.device
IgnoreOnIsolate=1

@ -0,0 +1,318 @@
// SPDX-License-Identifier: BSD-3-Clause
/*
* Copyright (c) 2009-2012,2016,2023 Microsoft Corp.
* Copyright (c) 2012 NetApp Inc.
* Copyright (c) 2012 Citrix Inc.
* All rights reserved.
*/
#include <errno.h>
#include <fcntl.h>
#include <emmintrin.h>
#include <linux/limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/uio.h>
#include <unistd.h>
#include "vmbus_bufring.h"
/**
* Compiler barrier.
*
* Guarantees that operation reordering does not occur at compile time
* for operations directly before and after the barrier.
*/
#define rte_compiler_barrier() ({ asm volatile ("" : : : "memory"); })
#define VMBUS_RQST_ERROR 0xFFFFFFFFFFFFFFFF
#define ALIGN(val, align) ((typeof(val))((val) & (~((typeof(val))((align) - 1)))))
void *vmbus_uio_map(int *fd, int size)
{
void *map;
map = mmap(NULL, 2 * size, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0);
if (map == MAP_FAILED)
return NULL;
return map;
}
/* Increase bufring index by inc with wraparound */
static inline uint32_t vmbus_br_idxinc(uint32_t idx, uint32_t inc, uint32_t sz)
{
idx += inc;
if (idx >= sz)
idx -= sz;
return idx;
}
void vmbus_br_setup(struct vmbus_br *br, void *buf, unsigned int blen)
{
br->vbr = buf;
br->windex = br->vbr->windex;
br->dsize = blen - sizeof(struct vmbus_bufring);
}
static inline __always_inline void
rte_smp_mb(void)
{
asm volatile("lock addl $0, -128(%%rsp); " ::: "memory");
}
static inline int
rte_atomic32_cmpset(volatile uint32_t *dst, uint32_t exp, uint32_t src)
{
uint8_t res;
asm volatile("lock ; "
"cmpxchgl %[src], %[dst];"
"sete %[res];"
: [res] "=a" (res), /* output */
[dst] "=m" (*dst)
: [src] "r" (src), /* input */
"a" (exp),
"m" (*dst)
: "memory"); /* no-clobber list */
return res;
}
static inline uint32_t
vmbus_txbr_copyto(const struct vmbus_br *tbr, uint32_t windex,
const void *src0, uint32_t cplen)
{
uint8_t *br_data = tbr->vbr->data;
uint32_t br_dsize = tbr->dsize;
const uint8_t *src = src0;
/* XXX use double mapping like Linux kernel? */
if (cplen > br_dsize - windex) {
uint32_t fraglen = br_dsize - windex;
/* Wrap-around detected */
memcpy(br_data + windex, src, fraglen);
memcpy(br_data, src + fraglen, cplen - fraglen);
} else {
memcpy(br_data + windex, src, cplen);
}
return vmbus_br_idxinc(windex, cplen, br_dsize);
}
/*
* Write scattered channel packet to TX bufring.
*
* The offset of this channel packet is written as a 64bits value
* immediately after this channel packet.
*
* The write goes through three stages:
* 1. Reserve space in ring buffer for the new data.
* Writer atomically moves priv_write_index.
* 2. Copy the new data into the ring.
* 3. Update the tail of the ring (visible to host) that indicates
* next read location. Writer updates write_index
*/
static int
vmbus_txbr_write(struct vmbus_br *tbr, const struct iovec iov[], int iovlen)
{
struct vmbus_bufring *vbr = tbr->vbr;
uint32_t ring_size = tbr->dsize;
uint32_t old_windex, next_windex, windex, total;
uint64_t save_windex;
int i;
total = 0;
for (i = 0; i < iovlen; i++)
total += iov[i].iov_len;
total += sizeof(save_windex);
/* Reserve space in ring */
do {
uint32_t avail;
/* Get current free location */
old_windex = tbr->windex;
/* Prevent compiler reordering this with calculation */
rte_compiler_barrier();
avail = vmbus_br_availwrite(tbr, old_windex);
/* If not enough space in ring, then tell caller. */
if (avail <= total)
return -EAGAIN;
next_windex = vmbus_br_idxinc(old_windex, total, ring_size);
/* Atomic update of next write_index for other threads */
} while (!rte_atomic32_cmpset(&tbr->windex, old_windex, next_windex));
/* Space from old..new is now reserved */
windex = old_windex;
for (i = 0; i < iovlen; i++)
windex = vmbus_txbr_copyto(tbr, windex, iov[i].iov_base, iov[i].iov_len);
/* Set the offset of the current channel packet. */
save_windex = ((uint64_t)old_windex) << 32;
windex = vmbus_txbr_copyto(tbr, windex, &save_windex,
sizeof(save_windex));
/* The region reserved should match region used */
if (windex != next_windex)
return -EINVAL;
/* Ensure that data is available before updating host index */
rte_compiler_barrier();
/* Checkin for our reservation. wait for our turn to update host */
while (!rte_atomic32_cmpset(&vbr->windex, old_windex, next_windex))
_mm_pause();
return 0;
}
int rte_vmbus_chan_send(struct vmbus_br *txbr, uint16_t type, void *data,
uint32_t dlen, uint32_t flags)
{
struct vmbus_chanpkt pkt;
unsigned int pktlen, pad_pktlen;
const uint32_t hlen = sizeof(pkt);
uint64_t pad = 0;
struct iovec iov[3];
int error;
pktlen = hlen + dlen;
pad_pktlen = ALIGN(pktlen, sizeof(uint64_t));
pkt.hdr.type = type;
pkt.hdr.flags = flags;
pkt.hdr.hlen = hlen >> VMBUS_CHANPKT_SIZE_SHIFT;
pkt.hdr.tlen = pad_pktlen >> VMBUS_CHANPKT_SIZE_SHIFT;
pkt.hdr.xactid = VMBUS_RQST_ERROR;
iov[0].iov_base = &pkt;
iov[0].iov_len = hlen;
iov[1].iov_base = data;
iov[1].iov_len = dlen;
iov[2].iov_base = &pad;
iov[2].iov_len = pad_pktlen - pktlen;
error = vmbus_txbr_write(txbr, iov, 3);
return error;
}
static inline uint32_t
vmbus_rxbr_copyfrom(const struct vmbus_br *rbr, uint32_t rindex,
void *dst0, size_t cplen)
{
const uint8_t *br_data = rbr->vbr->data;
uint32_t br_dsize = rbr->dsize;
uint8_t *dst = dst0;
if (cplen > br_dsize - rindex) {
uint32_t fraglen = br_dsize - rindex;
/* Wrap-around detected. */
memcpy(dst, br_data + rindex, fraglen);
memcpy(dst + fraglen, br_data, cplen - fraglen);
} else {
memcpy(dst, br_data + rindex, cplen);
}
return vmbus_br_idxinc(rindex, cplen, br_dsize);
}
/* Copy data from receive ring but don't change index */
static int
vmbus_rxbr_peek(const struct vmbus_br *rbr, void *data, size_t dlen)
{
uint32_t avail;
/*
* The requested data and the 64bits channel packet
* offset should be there at least.
*/
avail = vmbus_br_availread(rbr);
if (avail < dlen + sizeof(uint64_t))
return -EAGAIN;
vmbus_rxbr_copyfrom(rbr, rbr->vbr->rindex, data, dlen);
return 0;
}
/*
* Copy data from receive ring and change index
* NOTE:
* We assume (dlen + skip) == sizeof(channel packet).
*/
static int
vmbus_rxbr_read(struct vmbus_br *rbr, void *data, size_t dlen, size_t skip)
{
struct vmbus_bufring *vbr = rbr->vbr;
uint32_t br_dsize = rbr->dsize;
uint32_t rindex;
if (vmbus_br_availread(rbr) < dlen + skip + sizeof(uint64_t))
return -EAGAIN;
/* Record where host was when we started read (for debug) */
rbr->windex = rbr->vbr->windex;
/*
* Copy channel packet from RX bufring.
*/
rindex = vmbus_br_idxinc(rbr->vbr->rindex, skip, br_dsize);
rindex = vmbus_rxbr_copyfrom(rbr, rindex, data, dlen);
/*
* Discard this channel packet's 64bits offset, which is useless to us.
*/
rindex = vmbus_br_idxinc(rindex, sizeof(uint64_t), br_dsize);
/* Update the read index _after_ the channel packet is fetched. */
rte_compiler_barrier();
vbr->rindex = rindex;
return 0;
}
int rte_vmbus_chan_recv_raw(struct vmbus_br *rxbr,
void *data, uint32_t *len)
{
struct vmbus_chanpkt_hdr pkt;
uint32_t dlen, bufferlen = *len;
int error;
error = vmbus_rxbr_peek(rxbr, &pkt, sizeof(pkt));
if (error)
return error;
if (unlikely(pkt.hlen < VMBUS_CHANPKT_HLEN_MIN))
/* XXX this channel is dead actually. */
return -EIO;
if (unlikely(pkt.hlen > pkt.tlen))
return -EIO;
/* Length are in quad words */
dlen = pkt.tlen << VMBUS_CHANPKT_SIZE_SHIFT;
*len = dlen;
/* If caller buffer is not large enough */
if (unlikely(dlen > bufferlen))
return -ENOBUFS;
/* Read data and skip packet header */
error = vmbus_rxbr_read(rxbr, data, dlen, 0);
if (error)
return error;
/* Return the number of bytes read */
return dlen + sizeof(uint64_t);
}

@ -0,0 +1,158 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#ifndef _VMBUS_BUF_H_
#define _VMBUS_BUF_H_
#include <stdbool.h>
#include <stdint.h>
#define __packed __attribute__((__packed__))
#define unlikely(x) __builtin_expect(!!(x), 0)
#define ICMSGHDRFLAG_TRANSACTION 1
#define ICMSGHDRFLAG_REQUEST 2
#define ICMSGHDRFLAG_RESPONSE 4
#define IC_VERSION_NEGOTIATION_MAX_VER_COUNT 100
#define ICMSG_HDR (sizeof(struct vmbuspipe_hdr) + sizeof(struct icmsg_hdr))
#define ICMSG_NEGOTIATE_PKT_SIZE(icframe_vercnt, icmsg_vercnt) \
(ICMSG_HDR + sizeof(struct icmsg_negotiate) + \
(((icframe_vercnt) + (icmsg_vercnt)) * sizeof(struct ic_version)))
/*
* Channel packets
*/
/* Channel packet flags */
#define VMBUS_CHANPKT_TYPE_INBAND 0x0006
#define VMBUS_CHANPKT_TYPE_RXBUF 0x0007
#define VMBUS_CHANPKT_TYPE_GPA 0x0009
#define VMBUS_CHANPKT_TYPE_COMP 0x000b
#define VMBUS_CHANPKT_FLAG_NONE 0
#define VMBUS_CHANPKT_FLAG_RC 0x0001 /* report completion */
#define VMBUS_CHANPKT_SIZE_SHIFT 3
#define VMBUS_CHANPKT_SIZE_ALIGN BIT(VMBUS_CHANPKT_SIZE_SHIFT)
#define VMBUS_CHANPKT_HLEN_MIN \
(sizeof(struct vmbus_chanpkt_hdr) >> VMBUS_CHANPKT_SIZE_SHIFT)
/*
* Buffer ring
*/
struct vmbus_bufring {
volatile uint32_t windex;
volatile uint32_t rindex;
/*
* Interrupt mask {0,1}
*
* For TX bufring, host set this to 1, when it is processing
* the TX bufring, so that we can safely skip the TX event
* notification to host.
*
* For RX bufring, once this is set to 1 by us, host will not
* further dispatch interrupts to us, even if there are data
* pending on the RX bufring. This effectively disables the
* interrupt of the channel to which this RX bufring is attached.
*/
volatile uint32_t imask;
/*
* Win8 uses some of the reserved bits to implement
* interrupt driven flow management. On the send side
* we can request that the receiver interrupt the sender
* when the ring transitions from being full to being able
* to handle a message of size "pending_send_sz".
*
* Add necessary state for this enhancement.
*/
volatile uint32_t pending_send;
uint32_t reserved1[12];
union {
struct {
uint32_t feat_pending_send_sz:1;
};
uint32_t value;
} feature_bits;
/* Pad it to rte_mem_page_size() so that data starts on page boundary */
uint8_t reserved2[4028];
/*
* Ring data starts here + RingDataStartOffset
* !!! DO NOT place any fields below this !!!
*/
uint8_t data[];
} __packed;
struct vmbus_br {
struct vmbus_bufring *vbr;
uint32_t dsize;
uint32_t windex; /* next available location */
};
struct vmbus_chanpkt_hdr {
uint16_t type; /* VMBUS_CHANPKT_TYPE_ */
uint16_t hlen; /* header len, in 8 bytes */
uint16_t tlen; /* total len, in 8 bytes */
uint16_t flags; /* VMBUS_CHANPKT_FLAG_ */
uint64_t xactid;
} __packed;
struct vmbus_chanpkt {
struct vmbus_chanpkt_hdr hdr;
} __packed;
struct vmbuspipe_hdr {
unsigned int flags;
unsigned int msgsize;
} __packed;
struct ic_version {
unsigned short major;
unsigned short minor;
} __packed;
struct icmsg_negotiate {
unsigned short icframe_vercnt;
unsigned short icmsg_vercnt;
unsigned int reserved;
struct ic_version icversion_data[]; /* any size array */
} __packed;
struct icmsg_hdr {
struct ic_version icverframe;
unsigned short icmsgtype;
struct ic_version icvermsg;
unsigned short icmsgsize;
unsigned int status;
unsigned char ictransaction_id;
unsigned char icflags;
unsigned char reserved[2];
} __packed;
int rte_vmbus_chan_recv_raw(struct vmbus_br *rxbr, void *data, uint32_t *len);
int rte_vmbus_chan_send(struct vmbus_br *txbr, uint16_t type, void *data,
uint32_t dlen, uint32_t flags);
void vmbus_br_setup(struct vmbus_br *br, void *buf, unsigned int blen);
void *vmbus_uio_map(int *fd, int size);
/* Amount of space available for write */
static inline uint32_t vmbus_br_availwrite(const struct vmbus_br *br, uint32_t windex)
{
uint32_t rindex = br->vbr->rindex;
if (windex >= rindex)
return br->dsize - (windex - rindex);
else
return rindex - windex;
}
static inline uint32_t vmbus_br_availread(const struct vmbus_br *br)
{
return br->dsize - vmbus_br_availwrite(br, br->vbr->windex);
}
#endif /* !_VMBUS_BUF_H_ */

@ -3,9 +3,9 @@
# Hyper-V VSS daemon binary name
%global hv_vss_daemon hypervvssd
# Hyper-V FCOPY daemon binary name
%global hv_fcopy_daemon hypervfcopyd
%global hv_fcopy_uio_daemon hv_fcopy_uio_daemon
# snapshot version
%global snapver .20190303git
%global snapver .20220731git
# use hardened build
%global _hardened_build 1
# udev rules prefix
@ -13,10 +13,10 @@
Name: hyperv-daemons
Version: 0
Release: 0.42%{?snapver}%{?dist}
Release: 0.47%{?snapver}%{?dist}
Summary: Hyper-V daemons suite
License: GPLv2
License: GPL-2.0-only
URL: http://www.kernel.org
# Source files obtained from kernel upstream 4.17-rc1 (60cc43fc888428bb2f18f08997432d426a243338)
@ -36,32 +36,51 @@ Source100: hv_vss_daemon.c
Source101: hypervvssd.service
Source102: hypervvss.rules
# HYPERV FCOPY DAEMON
Source200: hv_fcopy_daemon.c
# HYPERV FCOPY UIO DAEMON
# source taken from https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/snapshot/linux-6.10-rc5.tar.gz
Source200: hv_fcopy_uio_daemon.c
Source201: hypervfcopyd.service
Source202: hypervfcopy.rules
Source202: vmbus_bufring.c
Source203: vmbus_bufring.h
# HYPERV TOOLS
Source301: lsvmbus
Patch0002: 0002-Do-not-set-NM_CONTROLLED-no.patch
Patch0004: 0004-Update-C-files-and-scripts-to-kernel-version-5.7-rc1.patch
Patch0005: 0005-Add-vmbus_testing-tool-build-files.patch
Patch0006: 0006-tools-hv-change-http-to-https-in-hv_kvp_daemon.c.patch
# For bz#2026371 - [RHEL9][Hyper-V]The /usr/libexec/hypervkvpd/hv_set_ifconfig need update for RHEL9 since the ifdown/ifup was not supported on RHEL9
Patch7: hpvd-hv_set_ifconfig.sh-Use-nmcli-commands.patch
# For bz#2026371 - [RHEL9][Hyper-V]The /usr/libexec/hypervkvpd/hv_set_ifconfig need update for RHEL9 since the ifdown/ifup was not supported on RHEL9
Patch8: hpvd-Use-filename-for-connection-profile.patch
# For bz#2122115 - [Hyper-V][RHEL-9] Cannot set gateway properly when set static IPADDR0,NETMASK0,GATEWAY in ifcfg-eth0
Patch9: hpvd-redhat-hv_set_if_config-Workaround-for-gateway-numbe.patch
# For bz#2139457 - [Hyper-V][RHEL9.2] Update Hyper-V-Daemons
Patch10: hpvd-tools-hv-Remove-an-extraneous-the.patch
# For bz#2139457 - [Hyper-V][RHEL9.2] Update Hyper-V-Daemons
Patch11: hpvd-tools-hv-kvp-remove-unnecessary-void-conversions.patch
# For bz#2218931 - [Hyper-V] [RHEL-9] /usr/sbin/vmbus_testing python script prints: "SyntaxWarning: "is" with a literal."
Patch12: hpvd-vmbus_testing-fix-wrong-python-syntax-for-integer-va.patch
# Source-git patches
# For RHEL-40107 - [Hyper-V][RHEL10] Request to update hypervkvpd related file /usr/libexec/hypervkvpd/hv_set_ifconfig same as RHEL 9.5 hv_set_ifconfig file.
# For RHEL-40679 - [Hyper-V][RHEL10] Request to update hyperv-daemons vmbus_testing, hv_kvp_daemon.c, hv_vss_daemon.c files as same as RHEL 9.5
Patch1: hpvd-Do-not-set-NM_CONTROLLED-no.patch
# For RHEL-40107 - [Hyper-V][RHEL10] Request to update hypervkvpd related file /usr/libexec/hypervkvpd/hv_set_ifconfig same as RHEL 9.5 hv_set_ifconfig file.
# For RHEL-40679 - [Hyper-V][RHEL10] Request to update hyperv-daemons vmbus_testing, hv_kvp_daemon.c, hv_vss_daemon.c files as same as RHEL 9.5
Patch2: hpvd-Add-vmbus_testing-tool-build-files.patch
# For RHEL-40107 - [Hyper-V][RHEL10] Request to update hypervkvpd related file /usr/libexec/hypervkvpd/hv_set_ifconfig same as RHEL 9.5 hv_set_ifconfig file.
# For RHEL-40679 - [Hyper-V][RHEL10] Request to update hyperv-daemons vmbus_testing, hv_kvp_daemon.c, hv_vss_daemon.c files as same as RHEL 9.5
Patch3: hpvd-hv_set_ifconfig.sh-Use-nmcli-commands.patch
# For RHEL-40107 - [Hyper-V][RHEL10] Request to update hypervkvpd related file /usr/libexec/hypervkvpd/hv_set_ifconfig same as RHEL 9.5 hv_set_ifconfig file.
# For RHEL-40679 - [Hyper-V][RHEL10] Request to update hyperv-daemons vmbus_testing, hv_kvp_daemon.c, hv_vss_daemon.c files as same as RHEL 9.5
Patch4: hpvd-Use-filename-for-connection-profile.patch
# For RHEL-40107 - [Hyper-V][RHEL10] Request to update hypervkvpd related file /usr/libexec/hypervkvpd/hv_set_ifconfig same as RHEL 9.5 hv_set_ifconfig file.
# For RHEL-40679 - [Hyper-V][RHEL10] Request to update hyperv-daemons vmbus_testing, hv_kvp_daemon.c, hv_vss_daemon.c files as same as RHEL 9.5
Patch5: hpvd-redhat-hv_set_if_config-Workaround-for-gateway-numbe.patch
# For RHEL-40107 - [Hyper-V][RHEL10] Request to update hypervkvpd related file /usr/libexec/hypervkvpd/hv_set_ifconfig same as RHEL 9.5 hv_set_ifconfig file.
# For RHEL-40679 - [Hyper-V][RHEL10] Request to update hyperv-daemons vmbus_testing, hv_kvp_daemon.c, hv_vss_daemon.c files as same as RHEL 9.5
Patch6: hpvd-tools-hv-Remove-an-extraneous-the.patch
# For RHEL-40107 - [Hyper-V][RHEL10] Request to update hypervkvpd related file /usr/libexec/hypervkvpd/hv_set_ifconfig same as RHEL 9.5 hv_set_ifconfig file.
# For RHEL-40679 - [Hyper-V][RHEL10] Request to update hyperv-daemons vmbus_testing, hv_kvp_daemon.c, hv_vss_daemon.c files as same as RHEL 9.5
Patch7: hpvd-tools-hv-kvp-remove-unnecessary-void-conversions.patch
# For RHEL-40107 - [Hyper-V][RHEL10] Request to update hypervkvpd related file /usr/libexec/hypervkvpd/hv_set_ifconfig same as RHEL 9.5 hv_set_ifconfig file.
# For RHEL-40679 - [Hyper-V][RHEL10] Request to update hyperv-daemons vmbus_testing, hv_kvp_daemon.c, hv_vss_daemon.c files as same as RHEL 9.5
Patch8: hpvd-vmbus_testing-fix-wrong-python-syntax-for-integer-va.patch
# For RHEL-40107 - [Hyper-V][RHEL10] Request to update hypervkvpd related file /usr/libexec/hypervkvpd/hv_set_ifconfig same as RHEL 9.5 hv_set_ifconfig file.
# For RHEL-40679 - [Hyper-V][RHEL10] Request to update hyperv-daemons vmbus_testing, hv_kvp_daemon.c, hv_vss_daemon.c files as same as RHEL 9.5
Patch9: hpvd-hv-hv_kvp_daemon-Support-for-keyfile-based-connectio.patch
# For RHEL-40107 - [Hyper-V][RHEL10] Request to update hypervkvpd related file /usr/libexec/hypervkvpd/hv_set_ifconfig same as RHEL 9.5 hv_set_ifconfig file.
# For RHEL-40679 - [Hyper-V][RHEL10] Request to update hyperv-daemons vmbus_testing, hv_kvp_daemon.c, hv_vss_daemon.c files as same as RHEL 9.5
Patch10: hpvd-hv-hv_kvp_daemon-Some-small-fixes-for-handling-NM-ke.patch
# For RHEL-40107 - [Hyper-V][RHEL10] Request to update hypervkvpd related file /usr/libexec/hypervkvpd/hv_set_ifconfig same as RHEL 9.5 hv_set_ifconfig file.
# For RHEL-40679 - [Hyper-V][RHEL10] Request to update hyperv-daemons vmbus_testing, hv_kvp_daemon.c, hv_vss_daemon.c files as same as RHEL 9.5
Patch11: hpvd-hv-hv_kvp_daemon-Handle-IPv4-and-Ipv6-combination-fo.patch
# For RHEL-40107 - [Hyper-V][RHEL10] Request to update hypervkvpd related file /usr/libexec/hypervkvpd/hv_set_ifconfig same as RHEL 9.5 hv_set_ifconfig file.
# For RHEL-40679 - [Hyper-V][RHEL10] Request to update hyperv-daemons vmbus_testing, hv_kvp_daemon.c, hv_vss_daemon.c files as same as RHEL 9.5
Patch12: hpvd-Changes-for-adding-keyfile-support-in-RHEL-specific-.patch
# Hyper-V is available only on x86 and aarch64 architectures
# The base empty (a.k.a. virtual) package can not be noarch
@ -70,10 +89,15 @@ ExclusiveArch: i686 x86_64 aarch64
Requires: hypervkvpd = %{version}-%{release}
Requires: hypervvssd = %{version}-%{release}
# FCopy UIO driver does not seem to be supported on arm
%ifnarch aarch64
Requires: hypervfcopyd = %{version}-%{release}
%else
Obsoletes: hypervfcopyd <= %{version}-%{release}
%endif
BuildRequires: gcc
%description
Suite of daemons that are needed when Linux guest
is running on Windows Host with Hyper-V.
@ -111,9 +135,10 @@ kernel driver. After this is done it waits for instructions
from Windows Host if to "freeze" or "thaw" the filesystem
on the Linux Guest.
%ifnarch aarch64
# FCOPY UIO driver does not seem to be saupported on arm etc.
%package -n hypervfcopyd
Summary: Hyper-V FCOPY daemon
Summary: Hyper-V FCOPY UIO daemon
Requires: %{name}-license = %{version}-%{release}
BuildRequires: systemd, kernel-headers
Requires(post): systemd
@ -126,7 +151,7 @@ for Linux Guest running on Hyper-V. The daemon enables host to copy
a file (over VMBUS) into the Linux Guest. The daemon first registers
with the kernel driver. After this is done it waits for instructions
from Windows Host.
%endif
%package license
Summary: License of the Hyper-V daemons suite
@ -150,27 +175,16 @@ cp -pvL %{SOURCE1} hv_kvp_daemon.c
cp -pvL %{SOURCE2} hv_get_dhcp_info.sh
cp -pvL %{SOURCE3} hv_get_dns_info.sh
cp -pvL %{SOURCE4} hv_set_ifconfig.sh
cp -pvL %{SOURCE5} hypervkvpd.service
cp -pvL %{SOURCE6} hypervkvp.rules
cp -pvL %{SOURCE100} hv_vss_daemon.c
cp -pvL %{SOURCE101} hypervvssd.service
cp -pvL %{SOURCE102} hypervvss.rules
cp -pvL %{SOURCE200} hv_fcopy_daemon.c
cp -pvL %{SOURCE201} hypervfcopyd.service
cp -pvL %{SOURCE202} hypervfcopy.rules
%ifnarch aarch64
cp -pvL %{SOURCE200} hv_fcopy_uio_daemon.c
cp -pvL %{SOURCE202} vmbus_bufring.c
cp -pvL %{SOURCE203} vmbus_bufring.h
%endif
cp -pvL %{SOURCE301} lsvmbus
%patch0002 -p1
%patch0004 -p1
%patch0005 -p1
%patch0006 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%autopatch -p1
%build
# HYPERV KVP DAEMON
@ -181,9 +195,13 @@ cp -pvL %{SOURCE301} lsvmbus
%{__cc} $RPM_OPT_FLAGS -c hv_vss_daemon.c
%{__cc} $RPM_LD_FLAGS hv_vss_daemon.o -o %{hv_vss_daemon}
# HYPERV FCOPY DAEMON
%{__cc} $RPM_OPT_FLAGS -c hv_fcopy_daemon.c
%{__cc} $RPM_LD_FLAGS hv_fcopy_daemon.o -o %{hv_fcopy_daemon}
%ifnarch aarch64
# HYPERV FCOPY UIO DAEMON
%{__cc} $RPM_OPT_FLAGS -c hv_fcopy_uio_daemon.c
%{__cc} $RPM_OPT_FLAGS -c vmbus_bufring.c
%{__cc} $RPM_LD_FLAGS vmbus_bufring.o hv_fcopy_uio_daemon.o -o %{hv_fcopy_uio_daemon}
%endif
%install
rm -rf %{buildroot}
@ -191,17 +209,22 @@ rm -rf %{buildroot}
mkdir -p %{buildroot}%{_sbindir}
install -p -m 0755 %{hv_kvp_daemon} %{buildroot}%{_sbindir}
install -p -m 0755 %{hv_vss_daemon} %{buildroot}%{_sbindir}
install -p -m 0755 %{hv_fcopy_daemon} %{buildroot}%{_sbindir}
%ifnarch aarch64
install -p -m 0755 %{hv_fcopy_uio_daemon} %{buildroot}%{_sbindir}
%endif
# Systemd unit file
mkdir -p %{buildroot}%{_unitdir}
install -p -m 0644 hypervkvpd.service %{buildroot}%{_unitdir}
install -p -m 0644 hypervvssd.service %{buildroot}%{_unitdir}
install -p -m 0644 hypervfcopyd.service %{buildroot}%{_unitdir}
install -p -m 0644 %{SOURCE5} %{buildroot}%{_unitdir}
install -p -m 0644 %{SOURCE101} %{buildroot}%{_unitdir}
%ifnarch aarch64
install -p -m 0644 %{SOURCE201} %{buildroot}%{_unitdir}
%endif
# Udev rules
mkdir -p %{buildroot}%{_udevrulesdir}
install -p -m 0644 hypervkvp.rules %{buildroot}%{_udevrulesdir}/%{udev_prefix}-hypervkvp.rules
install -p -m 0644 hypervvss.rules %{buildroot}%{_udevrulesdir}/%{udev_prefix}-hypervvss.rules
install -p -m 0644 hypervfcopy.rules %{buildroot}%{_udevrulesdir}/%{udev_prefix}-hypervfcopy.rules
install -p -m 0644 %{SOURCE6} %{buildroot}%{_udevrulesdir}/%{udev_prefix}-hypervkvp.rules
install -p -m 0644 %{SOURCE102} %{buildroot}%{_udevrulesdir}/%{udev_prefix}-hypervvss.rules
# Shell scripts for the KVP daemon
mkdir -p %{buildroot}%{_libexecdir}/%{hv_kvp_daemon}
install -p -m 0755 hv_get_dhcp_info.sh %{buildroot}%{_libexecdir}/%{hv_kvp_daemon}/hv_get_dhcp_info
@ -212,7 +235,7 @@ mkdir -p %{buildroot}%{_sharedstatedir}/hyperv
# Tools
install -p -m 0755 lsvmbus %{buildroot}%{_sbindir}/
sed -i 's,#!/usr/bin/env python,#!%{__python3},' %{buildroot}%{_sbindir}/lsvmbus
sed -i 's,#!/usr/bin/env python,#!/usr/bin/python3,' %{buildroot}%{_sbindir}/lsvmbus
install -p -m 0755 vmbus_testing %{buildroot}%{_sbindir}/
%post -n hypervkvpd
@ -245,7 +268,7 @@ fi
%preun -n hypervvssd
%systemd_preun hypervvssd.service
%ifnarch aarch64
%post -n hypervfcopyd
if [ $1 -gt 1 ] ; then
# Upgrade
@ -257,7 +280,7 @@ fi
%preun -n hypervfcopyd
%systemd_preun hypervfcopyd.service
%endif
%files
# the base package does not contain any files.
@ -275,10 +298,11 @@ fi
%{_unitdir}/hypervvssd.service
%{_udevrulesdir}/%{udev_prefix}-hypervvss.rules
%ifnarch aarch64
%files -n hypervfcopyd
%{_sbindir}/%{hv_fcopy_daemon}
%{_sbindir}/%{hv_fcopy_uio_daemon}
%{_unitdir}/hypervfcopyd.service
%{_udevrulesdir}/%{udev_prefix}-hypervfcopy.rules
%endif
%files license
%doc COPYING
@ -288,47 +312,73 @@ fi
%{_sbindir}/vmbus_testing
%changelog
* Mon Jul 10 2023 Miroslav Rezanina <mrezanin@redhat.com> - 0-0.42.20190303git
- hpvd-vmbus_testing-fix-wrong-python-syntax-for-integer-va.patch [bz#2218931]
- Resolves: bz#2218931
([Hyper-V] [RHEL-9] /usr/sbin/vmbus_testing python script prints: "SyntaxWarning: "is" with a literal.")
* Mon Nov 21 2022 Miroslav Rezanina <mrezanin@redhat.com> - 0-0.41.20190303git
- hpvd-redhat-hv_set_if_config-Workaround-for-gateway-numbe.patch [bz#2122115]
- hpvd-tools-hv-Remove-an-extraneous-the.patch [bz#2139457]
- hpvd-tools-hv-kvp-remove-unnecessary-void-conversions.patch [bz#2139457]
- Resolves: bz#2122115
([Hyper-V][RHEL-9] Cannot set gateway properly when set static IPADDR0,NETMASK0,GATEWAY in ifcfg-eth0)
- Resolves: bz#2139457
([Hyper-V][RHEL9.2] Update Hyper-V-Daemons)
* Fri Jul 29 2022 Miroslav Rezanina <mrezanin@redhat.com> - 0-0.40.20190303git
- hpvd-hypervkvpd.service-ordering-fixes.patch [bz#2103188]
- Resolves: bz#2103188
([Hyper-V][RHEL-9] hypervkvpd.service service ordering)
* Wed Dec 15 2021 Miroslav Rezanina <mrezanin@redhat.com> - 0-0.39.20190303git
- hpvd-hv_set_ifconfig.sh-Use-nmcli-commands.patch [bz#2026371]
- hpvd-Use-filename-for-connection-profile.patch [bz#2026371]
- Resolves: bz#2026371
([RHEL9][Hyper-V]The /usr/libexec/hypervkvpd/hv_set_ifconfig need update for RHEL9 since the ifdown/ifup was not supported on RHEL9)
* Mon Nov 08 2021 Miroslav Rezanina <mrezanin@redhat.com> - 0-0.38.20190303git
- hpvd-Enable-build-on-aarch64.patch [bz#2020148]
- Resolves: bz#2020148
([Hyper-V][RHEL9.0][ARM] No hyperv-daemons package built for aarch64 platform)
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 0-0.37.20190303git
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Mon May 10 2021 Miroslav Rezanina <mrezanin@redhat.com> - 0-0.36.20190303git
- Synchronize RHEL 8 changes [rhbz#1957651]
- Resolves: rhbz#1957651
([Hyper-V][RHEL-9] Update build to rhel format and syncup RHEL 8 content for hyperv-daemons.)
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 0-0.35.20190303git
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Tue Nov 26 2024 MSVSphere Packaging Team <packager@msvsphere-os.ru> - 0-0.47.20220731git
- Rebuilt for MSVSphere 10
* Fri Jul 12 2024 Miroslav Rezanina <mrezanin@redhat.com> - 0-0.47.20220731git
- hpvd-Add-support-for-newer-fcopy-UIO-hyperv-daemons-modul.patch [RHEL-44617]
- hpvd-Update-main-package-dep-on-hypervfcopyd-to-be-arch-d.patch [RHEL-44617]
- hpvd-Particularize-hypervfcopyd-service-requirements.patch [RHEL-44617]
- Resolves: RHEL-44617
([RHEL-10] Add support for fcopy UIO userland module in hyperv-daemons)
* Thu Jun 27 2024 Miroslav Rezanina <mrezanin@redhat.com> - 0-0.46.20220731git
- hpvd-Add-support-for-patching-hyperv-daemons.patch [RHEL-40107 RHEL-40679]
- hpvd-Do-not-set-NM_CONTROLLED-no.patch [RHEL-40107 RHEL-40679]
- hpvd-Add-vmbus_testing-tool-build-files.patch [RHEL-40107 RHEL-40679]
- hpvd-hv_set_ifconfig.sh-Use-nmcli-commands.patch [RHEL-40107 RHEL-40679]
- hpvd-Use-filename-for-connection-profile.patch [RHEL-40107 RHEL-40679]
- hpvd-redhat-hv_set_if_config-Workaround-for-gateway-numbe.patch [RHEL-40107 RHEL-40679]
- hpvd-tools-hv-Remove-an-extraneous-the.patch [RHEL-40107 RHEL-40679]
- hpvd-tools-hv-kvp-remove-unnecessary-void-conversions.patch [RHEL-40107 RHEL-40679]
- hpvd-vmbus_testing-fix-wrong-python-syntax-for-integer-va.patch [RHEL-40107 RHEL-40679]
- hpvd-hv-hv_kvp_daemon-Support-for-keyfile-based-connectio.patch [RHEL-40107 RHEL-40679]
- hpvd-hv-hv_kvp_daemon-Some-small-fixes-for-handling-NM-ke.patch [RHEL-40107 RHEL-40679]
- hpvd-hv-hv_kvp_daemon-Handle-IPv4-and-Ipv6-combination-fo.patch [RHEL-40107 RHEL-40679]
- hpvd-Changes-for-adding-keyfile-support-in-RHEL-specific-.patch [RHEL-40107 RHEL-40679]
- hpvd-Remove-hyperv_fcopy_daemon-as-the-c10s-kernel-does-n.patch [RHEL-40107 RHEL-40679]
- Resolves: RHEL-40107
([Hyper-V][RHEL10] Request to update hypervkvpd related file /usr/libexec/hypervkvpd/hv_set_ifconfig same as RHEL 9.5 hv_set_ifconfig file.)
- Resolves: RHEL-40679
([Hyper-V][RHEL10] Request to update hyperv-daemons vmbus_testing, hv_kvp_daemon.c, hv_vss_daemon.c files as same as RHEL 9.5)
* Mon Jun 24 2024 Troy Dawson <tdawson@redhat.com> - 0-0.45.20220731git
- Bump release for June 2024 mass rebuild
* Wed Jan 24 2024 Fedora Release Engineering <releng@fedoraproject.org> - 0-0.44.20220731git
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Sat Jan 20 2024 Fedora Release Engineering <releng@fedoraproject.org> - 0-0.43.20220731git
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Thu Jul 20 2023 Fedora Release Engineering <releng@fedoraproject.org> - 0-0.42.20220731git
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
* Tue May 30 2023 Vitaly Kuznetsov <vkuznets@redhat.com> - 0-0.41.20220731git
- Switch to SPDX identifiers for the license field
* Thu Jan 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 0-0.40.20220731git
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Tue Aug 02 2022 Vitaly Kuznetsov <vkuznets@redhat.com> - 0-0.39.20220731git
- Enable aarch64 build (#2111394)
- Fix typos in shell scripts
* Thu Jul 21 2022 Fedora Release Engineering <releng@fedoraproject.org> - 0-0.38.20220710git
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Thu Jul 14 2022 Vitaly Kuznetsov <vkuznets@redhat.com> - 0-0.37.20220710git
- Update to 5.19-rc6
* Fri Jul 01 2022 Chris Patterson <cpatterson@microsoft.com> - 0-0.37.20190303git
- Only start kvpd under Hyper-V
- Minimize dependencies for kvpd to ensure it starts before cloud-init
* Thu Jan 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 0-0.36.20190303git
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Thu Jul 22 2021 Fedora Release Engineering <releng@fedoraproject.org> - 0-0.35.20190303git
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 0-0.34.20190303git
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild

Loading…
Cancel
Save