Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue: 2935075 Fix Windows support #193

Merged
merged 2 commits into from
Aug 23, 2022

Conversation

EldarShalev
Copy link
Contributor

@EldarShalev EldarShalev commented Jul 20, 2022

Adding Windows support for sockperf including AF_UNIX.
Most of the code is added with #ifdef WIN32, so no impact is expected on linux.

Major changes include:

  1. AF_UNIX which in windows is only supported by SOCK_STREAM mode so no binding is needed from client side (thus no path_pid_num binding as provided in linux)
  2. Using new API s.a 'WSAStartup', 'DeleteFileA' (instead of unlink), 'closesocket()' instead of close(), etc..
  3. Working with <winsock2.h>

More about AF_UNIX in windows:
https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/

@swx-jenkins3
Copy link

Can one of the admins verify this patch?

src/client.cpp Outdated
if (setitimer(ITIMER_REAL, &timer, NULL)) {
log_err("ERROR: setitimer() failed when disarming");
}
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please consider moving os dependencies into os_abstarct.[h|cpp] if possible.
For example:

int os_settimer(timer)
{
#ifdef WIN32
#else
#endif
}

Pay attention that Linux and Windows return different values but it can be unified to linux style.

err = gai_strerror(res);
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please consider moving os dependencies into os_abstarct.[h|cpp] if possible.

src/sockperf.cpp Outdated Show resolved Hide resolved
src/sockperf.cpp Outdated Show resolved Hide resolved
src/sockperf.cpp Outdated
@@ -2337,7 +2352,12 @@ void cleanup() {
if (g_fds_array) {
for (ifd = 0; ifd <= s_fd_max; ifd++) {
if (g_fds_array[ifd]) {
#ifdef WIN32
closesocket(ifd);
WSACleanup();
Copy link
Collaborator

@igor-ivanov igor-ivanov Jul 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems as WSACleanup() call is wrong. It impacts the process and in fact called later as os_sock_cleanup

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

close() and closesocket() should be in os_abstract.h

Copy link
Contributor Author

@EldarShalev EldarShalev Jul 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. WSACleanup() must be called if WSAStartup() was called, So I do need to call it.
    doc- https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsastartup

The WSAStartup function must be the first Windows Sockets function called by an application or DLL. It allows an application or DLL to specify the version of Windows Sockets required and retrieve details of the specific Windows Sockets implementation. The application or DLL can only issue further Windows Sockets functions after successfully calling WSAStartup.
If the wVersion member of the WSADATA structure is unacceptable to the caller, the application or DLL should call WSACleanup to release the Winsock DLL resources and fail to initialize the Winsock application.

  1. I can move close and closesocket , just to clarify there is a different-
    close() is a unix function work on any file descriptor,
    closesocket() is a Windows-specific function, which works specifically with sockets.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. WSACleanup() must be called if WSAStartup() was called, So I do need to call it.
    doc- https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsastartup

The WSAStartup function must be the first Windows Sockets function called by an application or DLL. It allows an application or DLL to specify the version of Windows Sockets required and retrieve details of the specific Windows Sockets implementation. The application or DLL can only issue further Windows Sockets functions after successfully calling WSAStartup. If the wVersion member of the WSADATA structure is unacceptable to the caller, the application or DLL should call WSACleanup to release the Winsock DLL resources and fail to initialize the Winsock application.

  1. I can move close and closesocket , just to clarify there is a different-
    close() is a unix function work on any file descriptor,
    closesocket() is a Windows-specific function, which works specifically with sockets.

All above is correct but I said that WSACleanup() is called inside os_sock_cleanup() and no need to call WSACleanup() many times.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, missed that!
ok no problem

src/sockperf.cpp Outdated
unlink(g_fds_array[ifd]->server_addr.addr_un.sun_path);
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two ways here:
1 - wrapping if (s_user_params.addr.ss_family == AF_UNIX) { } by #ifndef WIN32
2 - do nothing if code under if (s_user_params.addr.ss_family == AF_UNIX) { } is compiled under windows. Code should not allow set unix socket under windows. In this case any condition as == AF_UNIX is FALSE

I prefer the option 2 (Less #ifdef constructions in the code)

Copy link
Contributor Author

@EldarShalev EldarShalev Jul 31, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In windows AF_UNIX is only supported in sock_stream, therefor the if statement for not using DGRAM.
I can do nothing, but then if someone use AF_UNIX in windows without --tcp option than the behavior is not defined.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the only place I left with #ifdef

src/sockperf.cpp Show resolved Hide resolved
src/sockperf.cpp Outdated
errno = EPERM;
exit_with_err("Please compile with VMA Extra API to use these options", SOCKPERF_ERR_FATAL);
}
#endif
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two ways here:
1 - wrapping if (s_user_params.fd_handler_type == SOCKETXTREME) { } by #ifndef WIN32
2 - do nothing if code under if (s_user_params.fd_handler_type == SOCKETXTREME) { } is compiled under windows. Code should not allow set SOCKETXTREME mode under windows. In this case any condition as == SOCKETXTREME is FALSE

I prefer the option 2 (Less #ifdef constructions in the code)

win/project/sockperf.vcxproj Outdated Show resolved Hide resolved
src/ticks.cpp Show resolved Hide resolved
@igor-ivanov igor-ivanov changed the title Adding Windows support issue: 2935075 Adding Windows support Jul 27, 2022
@igor-ivanov igor-ivanov changed the title issue: 2935075 Adding Windows support issue: 2935075 Add Windows support Jul 27, 2022
@igor-ivanov igor-ivanov changed the title issue: 2935075 Add Windows support issue: 2935075 Fix Windows support Jul 27, 2022
@EldarShalev EldarShalev force-pushed the windows branch 2 times, most recently from 80a4c16 to 5a98f5c Compare August 4, 2022 12:56
src/client.cpp Outdated Show resolved Hide resolved
src/common.h Show resolved Hide resolved
src/ip_address.cpp Outdated Show resolved Hide resolved
src/sockperf.cpp Outdated Show resolved Hide resolved
src/sockperf.cpp Show resolved Hide resolved
@@ -133,7 +133,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>__windows__;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove WIN32

@@ -115,7 +115,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>__windows__;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove WIN32

@@ -99,7 +99,7 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>__windows__;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove WIN32

@@ -85,7 +85,7 @@
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>__windows__;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove WIN32

src/common.cpp Outdated
@@ -64,7 +64,7 @@ std::string sockaddr_to_hostport(const struct sockaddr *addr)
if (addr->sa_family == AF_INET6) {
return "[" + std::string(hbuf) + "]:" + std::string(pbuf);
} else if (addr->sa_family == AF_UNIX) {
return std::string(pbuf) + " [UNIX]";
return std::string(addr->sa_data) + " [AF_UNIX]";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you show output

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in linux it's enough to give the pbuf because getnameinfo knows how to fill it with the address and the output is good.

In windows, I changed to more common way that works both for linux and windows with addr->sa_data which is the address directly.
Also changed UNIX to AF_UNIX - more generic
BTW, now I see another place to change..

af unix print

Copy link
Collaborator

@igor-ivanov igor-ivanov Aug 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that [AF_UNIX] is not needed
I prefer [fd=232] Binding to: \tmp\test ...

Can you please adapt https://github.com/Mellanox/sockperf/blob/sockperf_v2/src/iohandlers.cpp#L41
to
printf("[%2d] ADDR = %s # %s\n", list_count++, pbuf, PRINT_PROTOCOL(data->sock_type));
to get output as
[ 0] ADDR = \tmp\test # TCP

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just one thing, it's SOCK_STREAM / SOCK_DGRAM rather then TCP / UDP
so output like
[ 0] ADDR = \tmp\test # SOCK_STREAM

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just one thing, it's SOCK_STREAM / SOCK_DGRAM rather then TCP / UDP so output like [ 0] ADDR = \tmp\test # SOCK_STREAM

TCP/UDP is clear for end user and exist. I do not see benefits in SOCK_STREAM / SOCK_DGRAM

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's just a semantic we agreed in UDS patch, that AF_UNIX is not a TCP/UDP protocol and it might be confusing.
AF_INET + SOCK_STREAM = TCP
AF_UNIX + SOCK_STREAM !=TCP

That's why in the print I use PRINT_SOCKET_TYPE and not PRINT_PROTOCOL

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The behavior or AF_UNIX + SOCK_STREAM sockets is comparable to TCP.
So seeing
[ 0] ADDR = \tmp\test # TCP
in output points to AF_UNIX + SOCK_STREAM
and
[ 0] ADDR = 1.1.1.1 # TCP
points to AF_INET + SOCK_STREAM
Let keep identical output format for inet and unix

src/ip_address.h Outdated
#include <afunix.h>
typedef unsigned short int sa_family_t;

#else
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please consider #elif __linux__

src/sockperf.cpp Outdated
if (s_user_params.mode == MODE_SERVER)
#ifdef WIN32
DeleteFileA(g_fds_array[ifd]->server_addr.addr_un.sun_path);
#else
unlink(g_fds_array[ifd]->server_addr.addr_un.sun_path);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move DeleteFileA / unlink into os_abstract.
consider using remove() instead of DeleteFileA

src/sockperf.cpp Outdated
@@ -3332,6 +3354,7 @@ int bringup(const int *p_daemonize) {
/* Setup VMA */
int _vma_pkts_desc_size = 0;


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove empty line

@igor-ivanov
Copy link
Collaborator

insert issue: 2935075 in the second commit title

Copy link
Collaborator

@igor-ivanov igor-ivanov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix commit title "issue 2935075: RM Adding Windows support" to "issue: 2935075 Fix Windows support"
and the second as "issue: 2935075 Add preprocessor definition for windows"

@EldarShalev EldarShalev force-pushed the windows branch 2 times, most recently from 4f45cc2 to a6c2e1a Compare August 10, 2022 13:24
@EldarShalev
Copy link
Contributor Author

Feedfile example:
feedfile

@EldarShalev EldarShalev force-pushed the windows branch 2 times, most recently from 17f5099 to 6bb155b Compare August 14, 2022 14:00
src/defs.h Outdated Show resolved Hide resolved
src/defs.h Outdated Show resolved Hide resolved
@agalanin-at-nvidia
Copy link
Collaborator

bot:retest

src/defs.h Outdated Show resolved Hide resolved
src/defs.h Outdated Show resolved Hide resolved
@EldarShalev EldarShalev force-pushed the windows branch 2 times, most recently from 90f5085 to 84cddfd Compare August 16, 2022 12:42
@agalanin-at-nvidia
Copy link
Collaborator

bot:retest

bool success = vma_xlio_try_set_func_pointers();
if (!success) {
log_dbg("Failed to set function pointers for system functions.");
log_dbg("Check vma-xlio-redirect.cpp for functions which your OS implementation is missing. "
"Re-compile sockperf without them.");
}
#endif
int rc = 0;
if (os_sock_startup() == false) { // Only relevant for Windows
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we replace #endif above with #else and add #endif below this condition?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes agree since os_sock_startup() is only relevant for windows

@agalanin-at-nvidia
Copy link
Collaborator

bot:retest

@agalanin-at-nvidia
Copy link
Collaborator

bot:retest

@agalanin-at-nvidia
Copy link
Collaborator

bot:retest

@agalanin-at-nvidia
Copy link
Collaborator

bot:retest

@agalanin-at-nvidia
Copy link
Collaborator

bot:retest

doc/main.dox Outdated Show resolved Hide resolved
@igor-ivanov igor-ivanov merged commit 2ce4123 into Mellanox:sockperf_v2 Aug 23, 2022
@EldarShalev EldarShalev deleted the windows branch August 23, 2022 09:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants