SHA256
1
0
forked from pool/hyper-v

11 Commits

Author SHA256 Message Date
da5b0ca83c Accepting request 1294750 from Virtualization
- fcopy: Fix irregularities with size of ring buffer (a4131a50)
- fcopy: Fix incorrect file path conversion (0d86a8d6)

OBS-URL: https://build.opensuse.org/request/show/1294750
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/hyper-v?expand=0&rev=49
2025-07-22 10:54:00 +00:00
ef0842e123 - fcopy: Fix irregularities with size of ring buffer (a4131a50)
- fcopy: Fix incorrect file path conversion (0d86a8d6)

OBS-URL: https://build.opensuse.org/package/show/Virtualization/hyper-v?expand=0&rev=171
2025-07-21 07:35:38 +00:00
76e35909a4 Accepting request 1286999 from Virtualization
Automatic submission by obs-autosubmit

OBS-URL: https://build.opensuse.org/request/show/1286999
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/hyper-v?expand=0&rev=48
2025-06-20 14:48:29 +00:00
863abe6dca - Enable debug logs for hv_kvp_daemon (a9c0b33e) (bsc#1244154)
OBS-URL: https://build.opensuse.org/package/show/Virtualization/hyper-v?expand=0&rev=169
2025-06-12 15:54:42 +00:00
6a90f69586 - update route parsing in kvp daemon (9bbb8a07)
OBS-URL: https://build.opensuse.org/package/show/Virtualization/hyper-v?expand=0&rev=168
2025-06-12 15:30:54 +00:00
ab8183d4af adjust paths
OBS-URL: https://build.opensuse.org/package/show/Virtualization/hyper-v?expand=0&rev=167
2025-06-12 15:26:12 +00:00
b5f9af4b20 Accepting request 1236106 from Virtualization
- update route parsing in kvp daemon
- reduce resource usage in hv_kvp_daemon (175c71c2)
- reduce resouce usage in hv_get_dns_info helper (a4d024fe)
- hv_kvp_daemon: Pass NIC name to hv_get_dns_info as well (07dfa6e8)
- terminate fcopy daemon if read from uio fails (a9640fcd)
- change permissions of NetworkManager configuration file (91ae69c7)
- Fix a complier warning in the fcopy uio daemon (cb1b78f1)
- remove obsolete kvptest.ps1.txt which failed since a decade
- remove obsolete rpm postinstall code for SLE11SP2

OBS-URL: https://build.opensuse.org/request/show/1236106
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/hyper-v?expand=0&rev=47
2025-01-09 14:05:51 +00:00
9f552865e3 service_add_post
OBS-URL: https://build.opensuse.org/package/show/Virtualization/hyper-v?expand=0&rev=165
2025-01-09 07:39:41 +00:00
998704cdb5 +args
OBS-URL: https://build.opensuse.org/package/show/Virtualization/hyper-v?expand=0&rev=164
2025-01-07 20:14:30 +00:00
59fa582c95 +service_del_postun_without_restart
OBS-URL: https://build.opensuse.org/package/show/Virtualization/hyper-v?expand=0&rev=163
2025-01-07 20:12:20 +00:00
a23ad95876 - update route parsing in kvp daemon
- reduce resource usage in hv_kvp_daemon (175c71c2)
- reduce resouce usage in hv_get_dns_info helper (a4d024fe)
- hv_kvp_daemon: Pass NIC name to hv_get_dns_info as well (07dfa6e8)
- terminate fcopy daemon if read from uio fails (a9640fcd)
- change permissions of NetworkManager configuration file (91ae69c7)
- Fix a complier warning in the fcopy uio daemon (cb1b78f1)
- remove obsolete kvptest.ps1.txt which failed since a decade
- remove obsolete rpm postinstall code for SLE11SP2

OBS-URL: https://build.opensuse.org/package/show/Virtualization/hyper-v?expand=0&rev=162
2025-01-07 15:01:01 +00:00
7 changed files with 281 additions and 173 deletions

View File

@@ -1,3 +1,27 @@
-------------------------------------------------------------------
Sun Jul 20 20:20:20 UTC 2025 - ohering@suse.de
- fcopy: Fix irregularities with size of ring buffer (a4131a50)
- fcopy: Fix incorrect file path conversion (0d86a8d6)
-------------------------------------------------------------------
Fri Jun 6 06:06:06 UTC 2025 - ohering@suse.de
- Enable debug logs for hv_kvp_daemon (a9c0b33e) (bsc#1244154)
-------------------------------------------------------------------
Wed Jan 1 01:01:01 UTC 2025 - ohering@suse.de
- update route parsing in kvp daemon (9bbb8a07)
- reduce resource usage in hv_kvp_daemon (175c71c2)
- reduce resouce usage in hv_get_dns_info helper (a4d024fe)
- hv_kvp_daemon: Pass NIC name to hv_get_dns_info as well (07dfa6e8)
- terminate fcopy daemon if read from uio fails (a9640fcd)
- change permissions of NetworkManager configuration file (91ae69c7)
- Fix a complier warning in the fcopy uio daemon (cb1b78f1)
- remove obsolete kvptest.ps1.txt which failed since a decade
- remove obsolete rpm postinstall code for SLE11SP2
-------------------------------------------------------------------
Tue Oct 22 22:22:22 UTC 2024 - ohering@suse.de

View File

@@ -1,6 +1,6 @@
d=~/work/src/kernel/kerncvs.kernel.master
d=~/work/src/kernel/kerncvs.kernel.git
diff -u hyper-v.tools.hv.hv_vss_daemon.c ${d}/tools/hv/hv_vss_daemon.c
diff -u hyper-v.tools.hv.hv_kvp_daemon.c ${d}/tools/hv/hv_kvp_daemon.c
diff -u hyper-v.tools.hv.hv_fcopy_daemon.c ${d}/tools/hv/hv_fcopy_daemon.c
diff -u hyper-v.tools.hv.hv_fcopy_uio_daemon.c ${d}/tools/hv/hv_fcopy_uio_daemon.c
diff -u hyper-v.include.linux.hyperv.h ${d}/include/uapi/linux/hyperv.h
diff -u hyper-v.lsvmbus.py ${d}/tools/hv/lsvmbus

View File

@@ -1,49 +0,0 @@
# Windows PowerShell script to test Key Value Pair functionality
#
# http://blogs.msdn.com/b/virtual_pc_guy/archive/2008/11/18/hyper-v-script-looking-at-kvp-guestintrinsicexchangeitems.aspx
#
# Per default execution of scripts is disabled.
# http://technet.microsoft.com/en-us/library/ee176949.aspx
# The command 'Set-ExecutionPolicy RemoteSigned' will enable it.
#
# Filter for parsing XML data
filter Import-CimXml
{
# Create new XML object from input
$CimXml = [Xml]$_
$CimObj = New-Object -TypeName System.Object
# Iterate over the data and pull out just the value name and data for each entry
foreach ($CimProperty in $CimXml.SelectNodes("/INSTANCE/PROPERTY[@NAME='Name']"))
{
$CimObj | Add-Member -MemberType NoteProperty -Name $CimProperty.NAME -Value $CimProperty.VALUE
}
foreach ($CimProperty in $CimXml.SelectNodes("/INSTANCE/PROPERTY[@NAME='Data']"))
{
$CimObj | Add-Member -MemberType NoteProperty -Name $CimProperty.NAME -Value $CimProperty.VALUE
}
# Display output
$CimObj
}
# Prompt for the Hyper-V Server to use
$HyperVServer = Read-Host "Specify the Hyper-V Server to use (enter '.' for the local computer)"
# Prompt for the virtual machine to use
$VMName = Read-Host "Specify the name of the virtual machine"
# Get the virtual machine object
$query = "Select * From Msvm_ComputerSystem Where ElementName='" + $VMName + "'"
$Vm = gwmi -namespace root\virtualization -query $query -computername $HyperVServer
# Get the KVP Object
$query = "Associators of {$Vm} Where AssocClass=Msvm_SystemDevice ResultClass=Msvm_KvpExchangeComponent"
$Kvp = gwmi -namespace root\virtualization -query $query -computername $HyperVServer
Write-Host
Write-Host "Guest KVP information for" $VMName
# Filter the results
$Kvp.GuestIntrinsicExchangeItems | Import-CimXml

View File

@@ -43,7 +43,6 @@ URL: http://www.kernel.org
Version: 9
Release: 0
Source0: hyper-v.lsvmbus.py
Source5: hyper-v.kvptest.ps1.txt
Source7: hyper-v.compare-with-upstream.sh
Source8: hyper-v.tools.hv.vmbus_bufring.h
Source9: hyper-v.include.linux.hyperv.h
@@ -63,7 +62,6 @@ This package contains the Microsoft Hyper-V tools.
%prep
%setup -Tc
cp -avL %{S:5} kvptest.ps1.txt
cp -vL %{S:8} %vmbus_bufring.h
cp -vL %{S:9} %include_uapi_linux_hyperv.h
cp -vL %{S:10} .
@@ -263,58 +261,15 @@ chmod 755 %buildroot${bindir}/${helper}
%?python3_fix_shebang
%files
%doc kvptest.ps1.txt
%_unitdir/*
%_udevrulesdir/*
%_sbindir/*
%helper_dir
%pre
# hv_kvp_daemon in SLES11 SP2 stored temporary state files in /var/opt
# move them to /var/lib and remove old directory, if possible.
if test -d /var/opt/hyperv
then
if mkdir -p -v -m 0755 /var/lib/hyperv
then
cd /var/lib/hyperv
for oldfile in /var/opt/hyperv/ifcfg-* /var/opt/hyperv/.kvp_pool_*
do
if test -e "${oldfile}"
then
mv -vfb "${oldfile}" . || :
fi
done
cd - >/dev/null
fi
rmdir -v /var/opt/hyperv || :
fi
: nothing to do in case of systemd
# the relevant part is systemctl daemon-reload, due to udev triggers
%post
board_vendor=
product_name=
if cd /sys/class/dmi/id 2>/dev/null
then
if test -r board_vendor
then
board_vendor="`cat board_vendor`"
fi
if test -r product_name
then
product_name="`cat product_name`"
fi
cd - >/dev/null
fi
if test "${board_vendor}" = "Microsoft Corporation" -a "${product_name}" = "Virtual Machine"
then
: nothing to do in case of systemd
fi
%preun
: nothing to do in case of systemd
%service_add_post %hv_kvp_daemon %hv_vss_daemon %hv_fcopy_daemon %hv_fcopy_uio_daemon
%postun
# no restart on update because the daemon can not be restarted
: nothing to do in case of systemd
%service_del_postun_without_restart %hv_kvp_daemon %hv_vss_daemon %hv_fcopy_daemon %hv_fcopy_uio_daemon
%changelog

View File

@@ -35,9 +35,10 @@
#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_DEVICE_PATH(subdir) \
"/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/" #subdir
#define FCOPY_UIO_PATH FCOPY_DEVICE_PATH(uio)
#define FCOPY_CHANNELS_PATH FCOPY_DEVICE_PATH(channels)
#define FCOPY_VER_COUNT 1
static const int fcopy_versions[] = {
@@ -49,9 +50,62 @@ static const int fw_versions[] = {
UTIL_FW_VERSION
};
#define HV_RING_SIZE 0x4000 /* 16KB ring buffer size */
static uint32_t get_ring_buffer_size(void)
{
char ring_path[PATH_MAX];
DIR *dir;
struct dirent *entry;
struct stat st;
uint32_t ring_size = 0;
int retry_count = 0;
unsigned char desc[HV_RING_SIZE];
/* Find the channel directory */
dir = opendir(FCOPY_CHANNELS_PATH);
if (!dir) {
usleep(100 * 1000); /* Avoid race with kernel, wait 100ms and retry once */
dir = opendir(FCOPY_CHANNELS_PATH);
if (!dir) {
syslog(LOG_ERR, "Failed to open channels directory: %s", strerror(errno));
return 0;
}
}
retry_once:
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR && strcmp(entry->d_name, ".") != 0 &&
strcmp(entry->d_name, "..") != 0) {
snprintf(ring_path, sizeof(ring_path), "%s/%s/ring",
FCOPY_CHANNELS_PATH, entry->d_name);
if (stat(ring_path, &st) == 0) {
/*
* stat returns size of Tx, Rx rings combined,
* so take half of it for individual ring size.
*/
ring_size = (uint32_t)st.st_size / 2;
syslog(LOG_INFO, "Ring buffer size from %s: %u bytes",
ring_path, ring_size);
break;
}
}
}
if (!ring_size && retry_count == 0) {
retry_count = 1;
rewinddir(dir);
usleep(100 * 1000); /* Wait 100ms and retry once */
goto retry_once;
}
closedir(dir);
if (!ring_size)
syslog(LOG_ERR, "Could not determine ring size");
return ring_size;
}
static unsigned char *desc;
static int target_fd;
static char target_fname[PATH_MAX];
@@ -64,8 +118,11 @@ static int hv_fcopy_create_file(char *file_name, char *path_name, __u32 flags)
filesize = 0;
p = path_name;
snprintf(target_fname, sizeof(target_fname), "%s/%s",
path_name, file_name);
if (snprintf(target_fname, sizeof(target_fname), "%s/%s",
path_name, file_name) >= sizeof(target_fname)) {
syslog(LOG_ERR, "target file name is too long: %s/%s", path_name, file_name);
goto done;
}
/*
* Check to see if the path is already in place; if not,
@@ -272,7 +329,7 @@ static void wcstoutf8(char *dest, const __u16 *src, size_t dest_size)
{
size_t len = 0;
while (len < dest_size) {
while (len < dest_size && *src) {
if (src[len] < 0x80)
dest[len++] = (char)(*src++);
else
@@ -284,27 +341,15 @@ static void wcstoutf8(char *dest, const __u16 *src, size_t dest_size)
static int hv_fcopy_start(struct hv_start_fcopy *smsg_in)
{
/*
* file_name and path_name should have same length with appropriate
* member of hv_start_fcopy.
*/
char file_name[W_MAX_PATH], path_name[W_MAX_PATH];
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));
if (!file_name || !path_name) {
free(file_name);
free(path_name);
syslog(LOG_ERR, "Can't allocate memory for file name and/or path name");
return HV_E_FAIL;
}
wcstoutf8(file_name, (__u16 *)in_file_name, file_size);
wcstoutf8(path_name, (__u16 *)in_path_name, path_size);
wcstoutf8(file_name, smsg_in->file_name, W_MAX_PATH - 1);
wcstoutf8(path_name, smsg_in->path_name, W_MAX_PATH - 1);
return hv_fcopy_create_file(file_name, path_name, smsg_in->copy_flags);
}
@@ -408,9 +453,9 @@ int main(int argc, char *argv[])
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};
uint32_t ring_size, len;
char uio_name[NAME_MAX] = {0};
char uio_dev_path[PATH_MAX] = {0};
static struct option long_options[] = {
{"help", no_argument, 0, 'h' },
@@ -439,7 +484,20 @@ int main(int argc, char *argv[])
openlog("HV_UIO_FCOPY", 0, LOG_USER);
syslog(LOG_INFO, "starting; pid is:%d", getpid());
fcopy_get_first_folder(FCOPY_UIO, uio_name);
ring_size = get_ring_buffer_size();
if (!ring_size) {
ret = -ENODEV;
goto exit;
}
desc = malloc(ring_size * sizeof(unsigned char));
if (!desc) {
syslog(LOG_ERR, "malloc failed for desc buffer");
ret = -ENOMEM;
goto exit;
}
fcopy_get_first_folder(FCOPY_UIO_PATH, uio_name);
snprintf(uio_dev_path, sizeof(uio_dev_path), "/dev/%s", uio_name);
fcopy_fd = open(uio_dev_path, O_RDWR);
@@ -447,17 +505,17 @@ int main(int argc, char *argv[])
syslog(LOG_ERR, "open %s failed; error: %d %s",
uio_dev_path, errno, strerror(errno));
ret = fcopy_fd;
goto exit;
goto free_desc;
}
ring = vmbus_uio_map(&fcopy_fd, HV_RING_SIZE);
ring = vmbus_uio_map(&fcopy_fd, 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);
vmbus_br_setup(&txbr, ring, ring_size);
vmbus_br_setup(&rxbr, (char *)ring + ring_size, ring_size);
rxbr.vbr->imask = 0;
@@ -468,11 +526,13 @@ int main(int argc, char *argv[])
*/
ret = pread(fcopy_fd, &tmp, sizeof(int), 0);
if (ret < 0) {
if (errno == EINTR || errno == EAGAIN)
continue;
syslog(LOG_ERR, "pread failed: %s", strerror(errno));
continue;
goto close;
}
len = HV_RING_SIZE;
len = ring_size;
ret = rte_vmbus_chan_recv_raw(&rxbr, desc, &len);
if (unlikely(ret <= 0)) {
/* This indicates a failure to communicate (or worse) */
@@ -492,6 +552,8 @@ int main(int argc, char *argv[])
}
close:
close(fcopy_fd);
free_desc:
free(desc);
exit:
return ret;
}

View File

@@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/sh
# This script parses /etc/resolv.conf to retrive DNS information.
# In the interest of keeping the KVP daemon code free of distro specific
@@ -10,7 +10,8 @@
# this script can be based on the Network Manager APIs for retrieving DNS
# entries.
if test -r /etc/resolv.conf
if test -f /etc/resolv.conf
then
awk -- '/^nameserver/ { print $2 }' /etc/resolv.conf
exec awk -- '/^nameserver/ { print $2 }' /etc/resolv.conf
fi
exit 0

View File

@@ -24,6 +24,7 @@
#include <sys/poll.h>
#include <sys/utsname.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -83,6 +84,7 @@ enum {
};
static int in_hand_shake;
static int debug;
static char *os_name = "";
static char *os_major = "";
@@ -183,6 +185,20 @@ static void kvp_update_file(int pool)
kvp_release_lock(pool);
}
static void kvp_dump_initial_pools(int pool)
{
int i;
syslog(LOG_DEBUG, "===Start dumping the contents of pool %d ===\n",
pool);
for (i = 0; i < kvp_file_info[pool].num_records; i++)
syslog(LOG_DEBUG, "pool: %d, %d/%d key=%s val=%s\n",
pool, i + 1, kvp_file_info[pool].num_records,
kvp_file_info[pool].records[i].key,
kvp_file_info[pool].records[i].value);
}
static void kvp_update_mem_state(int pool)
{
FILE *filep;
@@ -270,6 +286,8 @@ static int kvp_file_init(void)
return 1;
kvp_file_info[i].num_records = 0;
kvp_update_mem_state(i);
if (debug)
kvp_dump_initial_pools(i);
}
return 0;
@@ -297,6 +315,9 @@ static int kvp_key_delete(int pool, const __u8 *key, int key_size)
* Found a match; just move the remaining
* entries up.
*/
if (debug)
syslog(LOG_DEBUG, "%s: deleting the KVP: pool=%d key=%s val=%s",
__func__, pool, record[i].key, record[i].value);
if (i == (num_records - 1)) {
kvp_file_info[pool].num_records--;
kvp_update_file(pool);
@@ -315,20 +336,36 @@ static int kvp_key_delete(int pool, const __u8 *key, int key_size)
kvp_update_file(pool);
return 0;
}
if (debug)
syslog(LOG_DEBUG, "%s: could not delete KVP: pool=%d key=%s. Record not found",
__func__, pool, key);
return 1;
}
static int kvp_key_add_or_modify(int pool, const __u8 *key, int key_size,
const __u8 *value, int value_size)
{
int i;
int num_records;
struct kvp_record *record;
int num_records;
int num_blocks;
int i;
if (debug)
syslog(LOG_DEBUG, "%s: got a KVP: pool=%d key=%s val=%s",
__func__, pool, key, value);
if ((key_size > HV_KVP_EXCHANGE_MAX_KEY_SIZE) ||
(value_size > HV_KVP_EXCHANGE_MAX_VALUE_SIZE))
(value_size > HV_KVP_EXCHANGE_MAX_VALUE_SIZE)) {
syslog(LOG_ERR, "%s: Too long key or value: key=%s, val=%s",
__func__, key, value);
if (debug)
syslog(LOG_DEBUG, "%s: Too long key or value: pool=%d, key=%s, val=%s",
__func__, pool, key, value);
return 1;
}
/*
* First update the in-memory state.
@@ -348,6 +385,9 @@ static int kvp_key_add_or_modify(int pool, const __u8 *key, int key_size,
*/
memcpy(record[i].value, value, value_size);
kvp_update_file(pool);
if (debug)
syslog(LOG_DEBUG, "%s: updated: pool=%d key=%s val=%s",
__func__, pool, key, value);
return 0;
}
@@ -359,8 +399,10 @@ static int kvp_key_add_or_modify(int pool, const __u8 *key, int key_size,
record = realloc(record, sizeof(struct kvp_record) *
ENTRIES_PER_BLOCK * (num_blocks + 1));
if (record == NULL)
if (!record) {
syslog(LOG_ERR, "%s: Memory alloc failure", __func__);
return 1;
}
kvp_file_info[pool].num_blocks++;
}
@@ -368,6 +410,11 @@ static int kvp_key_add_or_modify(int pool, const __u8 *key, int key_size,
memcpy(record[i].key, key, key_size);
kvp_file_info[pool].records = record;
kvp_file_info[pool].num_records++;
if (debug)
syslog(LOG_DEBUG, "%s: added: pool=%d key=%s val=%s",
__func__, pool, key, value);
kvp_update_file(pool);
return 0;
}
@@ -677,6 +724,88 @@ static void kvp_process_ipconfig_file(char *cmd,
pclose(file);
}
static bool kvp_verify_ip_address(const void *address_string)
{
char verify_buf[sizeof(struct in6_addr)];
if (inet_pton(AF_INET, address_string, verify_buf) == 1)
return true;
if (inet_pton(AF_INET6, address_string, verify_buf) == 1)
return true;
return false;
}
static void kvp_extract_routes(const char *line, void **output, size_t *remaining)
{
static const char needle[] = "via ";
const char *match, *haystack = line;
while ((match = strstr(haystack, needle))) {
const char *address, *next_char;
/* Address starts after needle. */
address = match + strlen(needle);
/* The char following address is a space or end of line. */
next_char = strpbrk(address, " \t\\");
if (!next_char)
next_char = address + strlen(address) + 1;
/* Enough room for address and semicolon. */
if (*remaining >= (next_char - address) + 1) {
memcpy(*output, address, next_char - address);
/* Terminate string for verification. */
memcpy(*output + (next_char - address), "", 1);
if (kvp_verify_ip_address(*output)) {
/* Advance output buffer. */
*output += next_char - address;
*remaining -= next_char - address;
/* Each address needs a trailing semicolon. */
memcpy(*output, ";", 1);
*output += 1;
*remaining -= 1;
}
}
haystack = next_char;
}
}
static void kvp_get_gateway(void *buffer, size_t buffer_len)
{
static const char needle[] = "default ";
FILE *f;
void *output = buffer;
char *line = NULL;
size_t alloc_size = 0, remaining = buffer_len - 1;
ssize_t num_chars;
/* Show route information in a single line, for each address family */
f = popen("ip --oneline -4 route show;ip --oneline -6 route show", "r");
if (!f) {
/* Convert buffer into C-String. */
memcpy(output, "", 1);
return;
}
while ((num_chars = getline(&line, &alloc_size, f)) > 0) {
/* Skip short lines. */
if (num_chars <= strlen(needle))
continue;
/* Skip lines without default route. */
if (memcmp(line, needle, strlen(needle)))
continue;
/* Remove trailing newline to simplify further parsing. */
if (line[num_chars - 1] == '\n')
line[num_chars - 1] = '\0';
/* Search routes after match. */
kvp_extract_routes(line + strlen(needle), &output, &remaining);
}
/* Convert buffer into C-String. */
memcpy(output, "", 1);
free(line);
pclose(f);
}
static void kvp_get_ipconfig_info(char *if_name,
struct hv_kvp_ipaddr_value *buffer)
{
@@ -685,30 +814,7 @@ static void kvp_get_ipconfig_info(char *if_name,
char *p;
FILE *file;
/*
* Get the address of default gateway (ipv4).
*/
sprintf(cmd, "%s %s", "ip route show dev", if_name);
strcat(cmd, " | awk '/default/ {print $3 }'");
/*
* Execute the command to gather gateway info.
*/
kvp_process_ipconfig_file(cmd, (char *)buffer->gate_way,
(MAX_GATEWAY_SIZE * 2), INET_ADDRSTRLEN, 0);
/*
* Get the address of default gateway (ipv6).
*/
sprintf(cmd, "%s %s", "ip -f inet6 route show dev", if_name);
strcat(cmd, " | awk '/default/ {print $3 }'");
/*
* Execute the command to gather gateway info (ipv6).
*/
kvp_process_ipconfig_file(cmd, (char *)buffer->gate_way,
(MAX_GATEWAY_SIZE * 2), INET6_ADDRSTRLEN, 1);
kvp_get_gateway(buffer->gate_way, sizeof(buffer->gate_way));
/*
* Gather the DNS state.
@@ -725,7 +831,7 @@ static void kvp_get_ipconfig_info(char *if_name,
* .
*/
sprintf(cmd, KVP_SCRIPTS_PATH "%s", "hv_get_dns_info");
sprintf(cmd, "exec %s %s", KVP_SCRIPTS_PATH "hv_get_dns_info", if_name);
/*
* Execute the command to gather DNS info.
@@ -742,7 +848,7 @@ static void kvp_get_ipconfig_info(char *if_name,
* Enabled: DHCP enabled.
*/
sprintf(cmd, KVP_SCRIPTS_PATH "%s %s", "hv_get_dhcp_info", if_name);
sprintf(cmd, "exec %s %s", KVP_SCRIPTS_PATH "hv_get_dhcp_info", if_name);
file = popen(cmd, "r");
if (file == NULL)
@@ -1606,8 +1712,9 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
* invoke the external script to do its magic.
*/
str_len = snprintf(cmd, sizeof(cmd), KVP_SCRIPTS_PATH "%s %s %s",
"hv_set_ifconfig", if_filename, nm_filename);
str_len = snprintf(cmd, sizeof(cmd), "exec %s %s %s",
KVP_SCRIPTS_PATH "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.
@@ -1663,6 +1770,7 @@ void print_usage(char *argv[])
fprintf(stderr, "Usage: %s [options]\n"
"Options are:\n"
" -n, --no-daemon stay in foreground, don't daemonize\n"
" -d, --debug Enable debug logs(syslog debug by default)\n"
" -h, --help print this help\n", argv[0]);
}
@@ -1684,10 +1792,11 @@ int main(int argc, char *argv[])
static struct option long_options[] = {
{"help", no_argument, 0, 'h' },
{"no-daemon", no_argument, 0, 'n' },
{"debug", no_argument, 0, 'd' },
{0, 0, 0, 0 }
};
while ((opt = getopt_long(argc, argv, "hn", long_options,
while ((opt = getopt_long(argc, argv, "hnd", long_options,
&long_index)) != -1) {
switch (opt) {
case 'n':
@@ -1696,6 +1805,9 @@ int main(int argc, char *argv[])
case 'h':
print_usage(argv);
exit(0);
case 'd':
debug = 1;
break;
default:
print_usage(argv);
exit(EXIT_FAILURE);
@@ -1718,6 +1830,9 @@ int main(int argc, char *argv[])
*/
kvp_get_domain_name(full_domain_name, sizeof(full_domain_name));
if (debug)
syslog(LOG_INFO, "Logging debug info in syslog(debug)");
if (kvp_file_init()) {
syslog(LOG_ERR, "Failed to initialize the pools");
exit(EXIT_FAILURE);