Skip to content

Commit

Permalink
Support init and apply view in saiplayer and syncd (sonic-net#125)
Browse files Browse the repository at this point in the history
  • Loading branch information
kcudnik authored and Shuotian Cheng committed Nov 15, 2016
1 parent 333c01b commit 1f746ab
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 32 deletions.
1 change: 1 addition & 0 deletions debian/libsairedis-dev.install
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lib/inc/sairedis.h usr/include/sai
4 changes: 2 additions & 2 deletions lib/src/sai_redis_record.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ std::string getTimestamp()
return std::string(buffer);
}

// currenly true by default for debugging
volatile bool g_record = true;
// recording needs to be enabled explicitly
volatile bool g_record = false;

std::ofstream recording;
std::mutex g_recordMutex;
Expand Down
23 changes: 23 additions & 0 deletions lib/src/sai_redis_switch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
sai_switch_notification_t redis_switch_notifications;

bool g_switchInitialized = false;
volatile bool g_asicInitViewMode = false; // default mode is apply mode
volatile bool g_run = false;

std::shared_ptr<std::thread> notification_thread;
Expand Down Expand Up @@ -121,6 +122,8 @@ sai_status_t redis_initialize_switch(

g_run = true;

g_asicInitViewMode = false;

setRecording(g_record);

SWSS_LOG_DEBUG("creating notification thread");
Expand Down Expand Up @@ -228,6 +231,14 @@ sai_status_t sai_redis_internal_notify_syncd(

std::vector<swss::FieldValueTuple> entry;

// ASIC INIT/APPLY view with small letter 'a'
// and response is recorded as capital letter 'A'

if (g_record)
{
recordLine("a|" + key);
}

g_asicState->set(key, entry, "notify");

swss::Select s;
Expand Down Expand Up @@ -260,6 +271,11 @@ sai_status_t sai_redis_internal_notify_syncd(
continue;
}

if (g_record)
{
recordLine("A|" + opkey);
}

sai_status_t status;
sai_deserialize_status(opkey, status);

Expand All @@ -272,6 +288,11 @@ sai_status_t sai_redis_internal_notify_syncd(

SWSS_LOG_ERROR("notify syncd failed to get response");

if (g_record)
{
recordLine("A|SAI_STATUS_FAILURE");
}

return SAI_STATUS_FAILURE;
}

Expand All @@ -297,11 +318,13 @@ sai_status_t sai_redis_notify_syncd(
case SAI_REDIS_NOTIFY_SYNCD_INIT_VIEW:
SWSS_LOG_NOTICE("sending syncd INIT view");
op = SYNCD_INIT_VIEW;
g_asicInitViewMode = true;
break;

case SAI_REDIS_NOTIFY_SYNCD_APPLY_VIEW:
SWSS_LOG_NOTICE("sending syncd APPLY view");
op = SYNCD_APPLY_VIEW;
g_asicInitViewMode = false;
break;

default:
Expand Down
134 changes: 109 additions & 25 deletions saiplayer/saiplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <string>

#include <getopt.h>
#include <unistd.h>

#include "string.h"
extern "C" {
Expand Down Expand Up @@ -944,8 +945,95 @@ void handle_get_response(
match_redis_with_rec(object_type, get_attr_count, get_attr_list, attr_count, attr_list);
}

void performSleep(const std::string& line)
{
SWSS_LOG_ENTER();

// timestamp|action|sleeptime
auto v = swss::tokenize(line, '|');

if (v.size() < 3)
{
SWSS_LOG_ERROR("invalid line %s", line.c_str());
exit(EXIT_FAILURE);
}

uint32_t useconds;
sai_deserialize_number(v[2], useconds);

if (useconds > 0)
{
useconds *= 1000; // 1ms resolution is enough for sleep

SWSS_LOG_NOTICE("usleep(%lu)", useconds);
usleep(useconds);
}
}

bool g_notifySyncd = true;

void performNotifySyncd(const std::string& request, const std::string response)
{
SWSS_LOG_ENTER();

// timestamp|action|data
auto r = swss::tokenize(request, '|');
auto R = swss::tokenize(response, '|');

if (r[1] != "a" || R[1] != "A")
{
SWSS_LOG_ERROR("invalid syncd notify request/response %s/%s", request.c_str(), response.c_str());
exit(EXIT_FAILURE);
}

if (g_notifySyncd == false)
{
SWSS_LOG_NOTICE("skipping notify syncd, selected by user");
return;
}

// tell syncd that we are compiling new view
sai_attribute_t attr;
attr.id = SAI_REDIS_SWITCH_ATTR_NOTIFY_SYNCD;

const std::string requestAction = r[2];

if (requestAction == SYNCD_INIT_VIEW)
{
attr.value.s32 = SAI_REDIS_NOTIFY_SYNCD_INIT_VIEW;
}
else if (requestAction == SYNCD_APPLY_VIEW)
{
attr.value.s32 = SAI_REDIS_NOTIFY_SYNCD_APPLY_VIEW;
}
else
{
SWSS_LOG_ERROR("invalid syncd notify request: %s", request.c_str());
exit(EXIT_FAILURE);
}

sai_status_t status = sai_switch_api->set_switch_attribute(&attr);

const std::string& responseStatus = R[2];

sai_status_t response_status;
sai_deserialize_status(responseStatus, response_status);

if (status != response_status)
{
SWSS_LOG_ERROR("response status %s is differnt than syncd status %s", responseStatus.c_str(), sai_serialize_status(status).c_str());
exit(EXIT_FAILURE);
}

if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("failed to notify syncd %s", sai_serialize_status(status).c_str());
exit(EXIT_FAILURE);
}

// OK
}

int replay(int argc, char **argv)
{
//swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_DEBUG);
Expand Down Expand Up @@ -973,15 +1061,6 @@ int replay(int argc, char **argv)

std::string line;

if (g_notifySyncd)
{
// tell syncd that we are compiling new view
sai_attribute_t attr;
attr.id = SAI_REDIS_SWITCH_ATTR_NOTIFY_SYNCD;
attr.value.s32 = SAI_REDIS_NOTIFY_SYNCD_INIT_VIEW;
EXIT_ON_ERROR(sai_switch_api->set_switch_attribute(&attr));
}

while (std::getline(infile, line))
{
// std::cout << "processing " << line << std::endl;
Expand All @@ -994,6 +1073,27 @@ int replay(int argc, char **argv)

switch (op)
{
case 'a':
{
std::string response;

do
{
// this line may be notification, we need to skip
if (!std::getline(infile, response))
{
SWSS_LOG_ERROR("failed to read next file from file, previous: %s", line.c_str());
exit(EXIT_FAILURE);
}
}
while (response[response.find_first_of("|")+1] == 'n');

performNotifySyncd(line, response);
}
continue;
case 'S':
performSleep(line);
continue;
case 'c':
api = SAI_COMMON_API_CREATE;
break;
Expand Down Expand Up @@ -1098,15 +1198,6 @@ int replay(int argc, char **argv)

infile.close();

if (g_notifySyncd)
{
// tell syncd that we want to apply this view
sai_attribute_t attr;
attr.id = SAI_REDIS_SWITCH_ATTR_NOTIFY_SYNCD;
attr.value.s32 = SAI_REDIS_NOTIFY_SYNCD_APPLY_VIEW;
EXIT_ON_ERROR(sai_switch_api->set_switch_attribute(&attr));
}

return 0;
}

Expand Down Expand Up @@ -1188,13 +1279,6 @@ int main(int argc, char **argv)

EXIT_ON_ERROR(sai_switch_api->initialize_switch(0, "", "", &switch_notifications));

// Disable recording
sai_attribute_t attr;
attr.id = SAI_REDIS_SWITCH_ATTR_RECORD;
attr.value.booldata = false;

EXIT_ON_ERROR(sai_switch_api->set_switch_attribute(&attr));

int exitcode = replay(argc, argv);

sai_switch_api->shutdown_switch(false);
Expand Down
9 changes: 4 additions & 5 deletions syncd/syncd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -795,14 +795,13 @@ sai_status_t notifySyncd(const std::string& op)

if (op == SYNCD_INIT_VIEW)
{
SWSS_LOG_ERROR("op = %s - not implemented", op.c_str());
exit_and_notify(EXIT_FAILURE);
SWSS_LOG_WARN("op = %s - not implemented, but sending success", op.c_str());
sendResponse(SAI_STATUS_SUCCESS);
}
else if (op == SYNCD_APPLY_VIEW)
{
SWSS_LOG_ERROR("op = %s - not implemented", op.c_str());
sendResponse(SAI_STATUS_NOT_IMPLEMENTED);
exit_and_notify(EXIT_FAILURE);
SWSS_LOG_WARN("op = %s - not implemented, but sending success", op.c_str());
sendResponse(SAI_STATUS_SUCCESS);
}
else
{
Expand Down

0 comments on commit 1f746ab

Please sign in to comment.