Skip to content

Commit cc7c72c

Browse files
author
Dave Brolley
committed
PR 12917 - Implement Compile-Server/Client Versioning: Part 1
- Client and server both include 'version' file as part of their request/response. - Client and server both check that they can deal with the other. - Currently both the client and the server can deal with all previous versions of the the other. - Both will reject an up level request/response from the other.
1 parent b0d0269 commit cc7c72c

File tree

5 files changed

+262
-100
lines changed

5 files changed

+262
-100
lines changed

csclient.cxx

+62-14
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <sys/times.h>
1717
#include <vector>
1818
#include <fstream>
19+
#include <sstream>
1920
#include <cassert>
2021
#include <cstdlib>
2122
#include <cstdio>
@@ -58,6 +59,7 @@ extern "C" {
5859
}
5960

6061
#include "nsscommon.h"
62+
#include "cscommon.h"
6163
#endif // HAVE_NSS
6264

6365
using namespace std;
@@ -819,7 +821,12 @@ compile_server_client::initialize ()
819821
int
820822
compile_server_client::create_request ()
821823
{
822-
int rc = 0;
824+
// Add the current protocol version.
825+
ostringstream protocol_version;
826+
protocol_version << CURRENT_CS_PROTOCOL_VERSION << " (0x" << hex << CURRENT_CS_PROTOCOL_VERSION << ")";
827+
int rc = write_to_file (client_tmpdir + "/version", protocol_version.str ());
828+
if (rc != 0)
829+
return rc;
823830

824831
// Add the script file or script option
825832
if (s.script_file != "")
@@ -1302,8 +1309,29 @@ compile_server_client::unpack_response ()
13021309
if (rc != 0)
13031310
{
13041311
clog << _F("Unable to unzip the server response '%s'\n", server_zipfile.c_str());
1312+
return rc;
13051313
}
13061314

1315+
// Determine the server protocol version.
1316+
server_version = CS_PROTOCOL_VERSION (1, 0); // Assumed until discovered otherwise
1317+
string filename = server_tmpdir + "/version";
1318+
if (file_exists (filename))
1319+
read_from_file (filename, server_version);
1320+
1321+
// Make sure we can communicate with this server.
1322+
bool compatible = client_server_compatible (CURRENT_CS_PROTOCOL_VERSION, server_version);
1323+
if (s.verbose > 1 || ! compatible)
1324+
clog << _F("Server protocol version is 0x%x\n", server_version);
1325+
if (! compatible)
1326+
{
1327+
clog << _F("Unable to communicate with a server using protocol version 0x%x",
1328+
server_version);
1329+
return 1;
1330+
}
1331+
1332+
// Warn about the shortcomings of this server if it is down level.
1333+
show_server_compatibility (server_version);
1334+
13071335
// If the server's response contains a systemtap temp directory, move
13081336
// its contents to our temp directory.
13091337
glob_t globbuf;
@@ -1316,7 +1344,8 @@ compile_server_client::unpack_response ()
13161344
if (globbuf.gl_pathc > 1)
13171345
{
13181346
clog << _("Incorrect number of files in server response") << endl;
1319-
rc = 1; goto done;
1347+
rc = 1;
1348+
goto done;
13201349
}
13211350

13221351
assert (globbuf.gl_pathc == 1);
@@ -1344,26 +1373,31 @@ compile_server_client::unpack_response ()
13441373
if (rc != 0)
13451374
{
13461375
clog << _F("Unable to link '%s' to '%s':%s\n",
1347-
oldname.c_str(), newname.c_str(), strerror(errno));
1376+
oldname.c_str(), newname.c_str(), strerror(errno));
13481377
goto done;
13491378
}
13501379
}
13511380
}
13521381
}
13531382

1354-
// Remove the output line due to the synthetic server-side -k
1355-
// Look for a message containing the name of the temporary directory.
1356-
// We can't key on the message text, because it may not always be in English, so
1357-
// instead, look for the quoted directory name.
1383+
// If the server version is less that 1.1, remove the output line due to the synthetic
1384+
// server-side -k. Look for a message containing the name of the temporary directory.
1385+
// We can look for the English message since server versions before 1.1 do not support
1386+
// localization.
1387+
if (server_version < CS_PROTOCOL_VERSION (1, 1))
1388+
{
1389+
cmd.clear();
1390+
cmd.push_back("sed");
1391+
cmd.push_back("-i");
1392+
cmd.push_back("/^Keeping temporary directory.*/ d");
1393+
cmd.push_back(server_tmpdir + "/stderr");
1394+
stap_system (s.verbose, cmd);
1395+
}
1396+
1397+
// Remove the output line due to the synthetic server-side -p4
13581398
cmd.clear();
13591399
cmd.push_back("sed");
13601400
cmd.push_back("-i");
1361-
cmd.push_back("/^Keeping temporary directory.*/ d"); // XXX: THIS DOES NOT WORK FOR NON-ENGLISH
1362-
cmd.push_back(server_tmpdir + "/stderr");
1363-
stap_system (s.verbose, cmd);
1364-
1365-
// Remove the output line due to the synthetic server-side -p4
1366-
cmd.erase(cmd.end() - 2, cmd.end());
13671401
cmd.push_back("/^.*\\.ko$/ d");
13681402
cmd.push_back(server_tmpdir + "/stdout");
13691403
stap_system (s.verbose, cmd);
@@ -1477,8 +1511,9 @@ compile_server_client::read_from_file (const string &fname, int &data)
14771511
return 1; // Failure
14781512
}
14791513

1514+
template <class T>
14801515
int
1481-
compile_server_client::write_to_file (const string &fname, const string &data)
1516+
compile_server_client::write_to_file (const string &fname, const T &data)
14821517
{
14831518
// C++ streams may not set errno in the even of a failure. However if we
14841519
// set it to 0 before each operation and it gets set during the operation,
@@ -1548,6 +1583,19 @@ compile_server_client::flush_to_stream (const string &fname, ostream &o)
15481583
clog << _("unknown error") << endl;
15491584
return 1; // Failure
15501585
}
1586+
1587+
void
1588+
compile_server_client::show_server_compatibility (int server_version)
1589+
{
1590+
// Locale sensitivity was added in version 1.1
1591+
if (server_version < CS_PROTOCOL_VERSION (1, 1))
1592+
{
1593+
if (s.verbose <= 1) // this message already printed?
1594+
clog << _F("Server protocol version is 0x%x\n", server_version);
1595+
clog << _("The server does not use localization information passed by the client\n");
1596+
}
1597+
}
1598+
15511599
#endif // HAVE_NSS
15521600

15531601
// Utility Functions.

csclient.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,20 @@ class compile_server_client
3737
int add_localization_variables();
3838

3939
int read_from_file (const std::string &fname, int &data);
40-
int write_to_file (const std::string &fname, const std::string &data);
40+
template <class T>
41+
int write_to_file (const std::string &fname, const T &data);
4142
int flush_to_stream (const std::string &fname, std::ostream &o);
4243

44+
void show_server_compatibility (int server_version);
45+
4346
systemtap_session &s;
4447
std::vector<std::string> private_ssl_dbs;
4548
std::vector<std::string> public_ssl_dbs;
4649
std::string client_tmpdir;
4750
std::string client_zipfile;
4851
std::string server_tmpdir;
4952
std::string server_zipfile;
53+
int server_version;
5054
unsigned argc;
5155
};
5256

cscommon.h

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#ifndef CSCOMMON_H
2+
#define CSCOMMON_H 1
3+
// Common functions and macros used by the compile-server and its client.
4+
5+
// Versioning system for the compile-server and client.
6+
#define CS_PROTOCOL_VERSION(major, minor) (((major) << 16) | (minor))
7+
8+
// Current protocol version.
9+
// Version 1.0
10+
// Original version
11+
// Version 1.1
12+
// Client:
13+
// - Passes localization variables to the server in the file client_tmpdir + "/locale"
14+
// Server:
15+
// - Applies localization variables passed from the client to stap during translation.
16+
// - Uses --tmpdir to specify temp directory to be used by stap, instead of -k, in order to avoid
17+
// parsing error messages in search of stap's randomly-generated temp dir. As a result, the
18+
// client no longer needs to remove stap's "Keeping temporary directory ..." message from the
19+
// server's stderr response.
20+
//
21+
#define CURRENT_CS_PROTOCOL_VERSION CS_PROTOCOL_VERSION (1, 1)
22+
23+
inline bool client_server_compatible (int client_version, int server_version)
24+
{
25+
// A present, all versions of the client and server can deal with one another. However reject
26+
// future counterparts using a higher protocol version.
27+
return client_version <= CURRENT_CS_PROTOCOL_VERSION &&
28+
server_version <= CURRENT_CS_PROTOCOL_VERSION;
29+
}
30+
31+
#endif // CSCOMMON_H

nsscommon.h

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#ifndef NSS_COMMON_H
2+
#define NSS_COMMON_H 1
3+
14
/* Used for parameters with default C++ values which are also called from C */
25
#if defined(c_plusplus) || defined(__cplusplus)
36
#define INIT(v,i) v = (i)
@@ -77,4 +80,6 @@ std::string get_cert_serial_number (const CERTCertificate *cert);
7780

7881
#endif // defined(c_plusplus) || defined(__cplusplus)
7982

83+
#endif // NSS_COMMON_H
84+
8085
/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */

0 commit comments

Comments
 (0)