Blame opasadb/path_tools/perf/opa_osd_perf.c

Packit Service 3470d1
/* BEGIN_ICS_COPYRIGHT2 ****************************************
Packit Service 3470d1
Packit Service 3470d1
Copyright (c) 2015-2017, Intel Corporation
Packit Service 3470d1
Packit Service 3470d1
Redistribution and use in source and binary forms, with or without
Packit Service 3470d1
modification, are permitted provided that the following conditions are met:
Packit Service 3470d1
Packit Service 3470d1
    * Redistributions of source code must retain the above copyright notice,
Packit Service 3470d1
      this list of conditions and the following disclaimer.
Packit Service 3470d1
    * Redistributions in binary form must reproduce the above copyright
Packit Service 3470d1
      notice, this list of conditions and the following disclaimer in the
Packit Service 3470d1
      documentation and/or other materials provided with the distribution.
Packit Service 3470d1
    * Neither the name of Intel Corporation nor the names of its contributors
Packit Service 3470d1
      may be used to endorse or promote products derived from this software
Packit Service 3470d1
      without specific prior written permission.
Packit Service 3470d1
Packit Service 3470d1
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit Service 3470d1
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit Service 3470d1
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Packit Service 3470d1
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
Packit Service 3470d1
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit Service 3470d1
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
Packit Service 3470d1
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
Packit Service 3470d1
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
Packit Service 3470d1
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit Service 3470d1
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit Service 3470d1
Packit Service 3470d1
** END_ICS_COPYRIGHT2   ****************************************/
Packit Service 3470d1
Packit Service 3470d1
/* [ICS VERSION STRING: unknown] */
Packit Service 3470d1
Packit Service 3470d1
/*
Packit Service 3470d1
 * This program is meant to determine the performance of the path query system. 
Packit Service 3470d1
 * The destination file is generated by the perf script: 
Packit Service 3470d1
 *     ./build_table.pl
Packit Service 3470d1
 * The resulting file guidtable_xxxxx can be used with the tool: 
Packit Service 3470d1
 *     ./opa_osd_perf -q 20000000 -p 0x8001 guidtable_xxxxx 
Packit Service 3470d1
 */
Packit Service 3470d1
#include <time.h>
Packit Service 3470d1
#include <locale.h>
Packit Service 3470d1
#include <langinfo.h>
Packit Service 3470d1
#include <stdio.h>
Packit Service 3470d1
#include <stdlib.h>
Packit Service 3470d1
#include <limits.h>
Packit Service 3470d1
#include <signal.h>
Packit Service 3470d1
#include <string.h>
Packit Service 3470d1
#include <unistd.h>
Packit Service 3470d1
#include <sys/socket.h>
Packit Service 3470d1
#include <arpa/inet.h>
Packit Service 3470d1
#include <sys/time.h>
Packit Service 3470d1
#include <infiniband/umad.h>
Packit Service 3470d1
#include "opasadb_path.h"
Packit Service 3470d1
#include "opasadb_debug.h"
Packit Service 3470d1
Packit Service 3470d1
#define MAX_SOURCE_PORTS (UMAD_CA_MAX_PORTS * UMAD_MAX_DEVICES)
Packit Service 3470d1
#define MAX_SIDS 8
Packit Service 3470d1
#define MAX_PKEYS 8
Packit Service 3470d1
Packit Service 3470d1
Packit Service 3470d1
#define DELIMITER ";"
Packit Service 3470d1
Packit Service 3470d1
static 	char remote[512];
Packit Service 3470d1
Packit Service 3470d1
typedef struct _src_record {
Packit Service 3470d1
	int disable;
Packit Service 3470d1
	uint64_t prefix;
Packit Service 3470d1
	uint64_t guid;
Packit Service 3470d1
	uint16_t base_lid;
Packit Service 3470d1
	uint16_t num_lids;
Packit Service 3470d1
	uint16_t port_num;
Packit Service 3470d1
	char hfi_num;
Packit Service 3470d1
} src_record;
Packit Service 3470d1
Packit Service 3470d1
typedef struct _record {
Packit Service 3470d1
	int disable;
Packit Service 3470d1
	int simulated;
Packit Service 3470d1
	uint64_t guid;
Packit Service 3470d1
	uint16_t lid;
Packit Service 3470d1
	char name[64];
Packit Service 3470d1
	int guid_fail_count;
Packit Service 3470d1
	int lid_fail_count;
Packit Service 3470d1
} record;
Packit Service 3470d1
Packit Service 3470d1
Packit Service 3470d1
static int 
Packit Service 3470d1
readline(FILE *f, char *s, int max)
Packit Service 3470d1
{
Packit Service 3470d1
	int i, c;
Packit Service 3470d1
Packit Service 3470d1
	memset(s,0,max);
Packit Service 3470d1
	i=0;
Packit Service 3470d1
	c=fgetc(f);
Packit Service 3470d1
Packit Service 3470d1
	while (c !='\n' && !feof(f) && i < max) {
Packit Service 3470d1
		s[i++]=c;
Packit Service 3470d1
		c=fgetc(f);
Packit Service 3470d1
	}
Packit Service 3470d1
	return i;
Packit Service 3470d1
}
Packit Service 3470d1
Packit Service 3470d1
Packit Service 3470d1
static int 
Packit Service 3470d1
readrecord(FILE *f, record *r)
Packit Service 3470d1
{
Packit Service 3470d1
	char *p, *l;
Packit Service 3470d1
	char buffer[1024];
Packit Service 3470d1
Packit Service 3470d1
	memset(r, 0, sizeof(record));
Packit Service 3470d1
Packit Service 3470d1
	if (readline(f, buffer, 1024) <=0)
Packit Service 3470d1
		return -1;
Packit Service 3470d1
			
Packit Service 3470d1
	r->disable = 0;
Packit Service 3470d1
Packit Service 3470d1
	p = strtok_r(buffer, DELIMITER, &l);
Packit Service 3470d1
	if (!p) 
Packit Service 3470d1
		return -1;
Packit Service 3470d1
	r->lid = htons(strtol(p,NULL,0));
Packit Service 3470d1
Packit Service 3470d1
	p = strtok_r(NULL, DELIMITER, &l);
Packit Service 3470d1
	if (!p) 
Packit Service 3470d1
		return -1;
Packit Service 3470d1
	r->guid = hton64(strtoull(p,NULL,0));
Packit Service 3470d1
	
Packit Service 3470d1
	p = strtok_r(NULL,DELIMITER, &l);
Packit Service 3470d1
	if (!p) 
Packit Service 3470d1
		return -1;
Packit Service 3470d1
	strcpy(r->name, p);
Packit Service 3470d1
	
Packit Service 3470d1
	r->simulated = strstr(p,"Sim") != NULL;
Packit Service 3470d1
	if (!r->simulated) {
Packit Service 3470d1
		/* parse name */
Packit Service 3470d1
		p = strstr(r->name," ");
Packit Service 3470d1
		if (p) 
Packit Service 3470d1
			*p=0;
Packit Service 3470d1
	}
Packit Service 3470d1
	
Packit Service 3470d1
	return 0;
Packit Service 3470d1
}
Packit Service 3470d1
Packit Service 3470d1
static void 
Packit Service 3470d1
usage(char **argv)
Packit Service 3470d1
{
Packit Service 3470d1
	fprintf(stderr, "Usage: %s [opts] guidtable\n", argv[0]);
Packit Service 3470d1
	fprintf(stderr, "Test performance of the distributed SA shared memory database.\n");
Packit Service 3470d1
	fprintf(stderr, "\toptions include:\n");
Packit Service 3470d1
	fprintf(stderr, "\t--help\n");
Packit Service 3470d1
	fprintf(stderr, "\t\tProvide this help text.\n");
Packit Service 3470d1
	fprintf(stderr, "\t-q <queries>\n");
Packit Service 3470d1
	fprintf(stderr, "\t\tRun at least <queries> queries.\n");
Packit Service 3470d1
	fprintf(stderr, "\t-p <pkey>\n");
Packit Service 3470d1
	fprintf(stderr, "\t\tInclude <pkey> in the searches.\n");
Packit Service 3470d1
	fprintf(stderr,"\t\t(Can be specified up to " add_quotes(MAX_PKEYS)
Packit Service 3470d1
		       " times.)\n");
Packit Service 3470d1
	fprintf(stderr, "\t-S <sid>\n");
Packit Service 3470d1
	fprintf(stderr, "\t\tInclude <sid> in the searches.\n");
Packit Service 3470d1
	fprintf(stderr,"\t\t(Can be specified up to " add_quotes(MAX_SIDS) 
Packit Service 3470d1
		       " times. Note that\n");
Packit Service 3470d1
	fprintf(stderr,"\t\tproviding both SIDs and pkeys may cause problems."
Packit Service 3470d1
		       ")\n");
Packit Service 3470d1
	fprintf(stderr, "\n");
Packit Service 3470d1
	fprintf(stderr,
Packit Service 3470d1
			"'guidtable' is a text file that lists the destination\n");
Packit Service 3470d1
	fprintf(stderr,
Packit Service 3470d1
			"guids and lids (i.e., from build_table.pl)\n");
Packit Service 3470d1
	fprintf(stderr,
Packit Service 3470d1
			"\nExample:\t%s -q 100000 -p 0x8001  guidtable\n", argv[0]);
Packit Service 3470d1
}
Packit Service 3470d1
Packit Service 3470d1
static record *dest_ports;
Packit Service 3470d1
static src_record src_ports[MAX_SOURCE_PORTS];
Packit Service 3470d1
int numsources = 0;
Packit Service 3470d1
Packit Service 3470d1
int
Packit Service 3470d1
get_sources(void)
Packit Service 3470d1
{
Packit Service 3470d1
	umad_port_t port;
Packit Service 3470d1
	char ca_names[UMAD_MAX_DEVICES][UMAD_CA_NAME_LEN];
Packit Service 3470d1
	int ca_count;
Packit Service 3470d1
	int i, err;
Packit Service 3470d1
Packit Service 3470d1
	ca_count = umad_get_cas_names(ca_names, UMAD_MAX_DEVICES);
Packit Service 3470d1
Packit Service 3470d1
	for (i = 0; i < ca_count; i++) {
Packit Service 3470d1
		umad_ca_t ca;
Packit Service 3470d1
		int j;
Packit Service 3470d1
		
Packit Service 3470d1
		err = umad_get_ca(ca_names[i], &ca);
Packit Service 3470d1
		if (err) {
Packit Service 3470d1
			_DBG_ERROR("Failed to open %s\n", ca_names[i]);
Packit Service 3470d1
			return -1;
Packit Service 3470d1
		}
Packit Service 3470d1
Packit Service 3470d1
		for (j = 1; j <= ca.numports; j++) {
Packit Service 3470d1
			err = umad_get_port(ca_names[i], j, &port);
Packit Service 3470d1
			if (err) {
Packit Service 3470d1
				_DBG_ERROR("Failed to get info on port %d of"
Packit Service 3470d1
					   " %s\n", j, ca_names[i]);
Packit Service 3470d1
				umad_release_ca(&ca);
Packit Service 3470d1
				return -1;
Packit Service 3470d1
			}
Packit Service 3470d1
Packit Service 3470d1
			if (port.state == IBV_PORT_ACTIVE) {
Packit Service 3470d1
				src_ports[numsources].disable = 
Packit Service 3470d1
					(port.state != IBV_PORT_ACTIVE);
Packit Service 3470d1
				src_ports[numsources].prefix = port.gid_prefix;
Packit Service 3470d1
				src_ports[numsources].guid = port.port_guid;
Packit Service 3470d1
				src_ports[numsources].base_lid = 
Packit Service 3470d1
					htons(port.base_lid);
Packit Service 3470d1
				src_ports[numsources].num_lids = 
Packit Service 3470d1
					1 << (port.lmc);
Packit Service 3470d1
				src_ports[numsources].port_num = j;
Packit Service 3470d1
				src_ports[numsources].hfi_num = i + 1;
Packit Service 3470d1
				numsources++;
Packit Service 3470d1
			}
Packit Service 3470d1
		}
Packit Service 3470d1
	}
Packit Service 3470d1
	return numsources;
Packit Service 3470d1
}
Packit Service 3470d1
Packit Service 3470d1
int 
Packit Service 3470d1
main(int argc, char **argv)
Packit Service 3470d1
{
Packit Service 3470d1
	FILE *f;
Packit Service 3470d1
	int c, err;
Packit Service 3470d1
	uint16_t port;
Packit Service 3470d1
	unsigned i, numdests;
Packit Service 3470d1
	uint64_t sid[MAX_SIDS];
Packit Service 3470d1
	unsigned pkey[MAX_PKEYS];
Packit Service 3470d1
	unsigned numpkeys, numsids;
Packit Service 3470d1
	uint64_t falsepos, falseneg, passes, queries, req_queries, perf;
Packit Service 3470d1
	struct timeval start_time, end_time, elapsed_time;
Packit Service 3470d1
	void *context;
Packit Service 3470d1
	struct ibv_context *hfi;
Packit Service 3470d1
	struct ibv_device *device;
Packit Service 3470d1
Packit Service 3470d1
	setlocale(LC_ALL, "");
Packit Service 3470d1
Packit Service 3470d1
	/* Default values. */
Packit Service 3470d1
	strcpy(remote,"strife");
Packit Service 3470d1
	port = 1;
Packit Service 3470d1
	req_queries = 0;
Packit Service 3470d1
	numdests = 1024;
Packit Service 3470d1
	numsources = 0;
Packit Service 3470d1
	numpkeys = 0;
Packit Service 3470d1
	numsids = 0;
Packit Service 3470d1
Packit Service 3470d1
	if (argc > 1){
Packit Service 3470d1
		if (!strcmp(argv[1], "--help")){
Packit Service 3470d1
			usage(argv);
Packit Service 3470d1
			exit(0);
Packit Service 3470d1
		}
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	while ((c = getopt(argc, argv, "d:q:p:S:")) != EOF) {
Packit Service 3470d1
		switch (c) {
Packit Service 3470d1
		case 'p':
Packit Service 3470d1
			if (numpkeys < MAX_PKEYS) {
Packit Service 3470d1
				pkey[numpkeys++] = htons(
Packit Service 3470d1
				   strtoul(optarg, NULL, 0));
Packit Service 3470d1
			} else {
Packit Service 3470d1
				_DBG_ERROR("Too many pkeys.\n");
Packit Service 3470d1
				return -1;
Packit Service 3470d1
			}
Packit Service 3470d1
			break;
Packit Service 3470d1
		case 'S':
Packit Service 3470d1
			if (numsids < MAX_SIDS) {
Packit Service 3470d1
				sid[numsids++] = hton64(
Packit Service 3470d1
				   strtoull(optarg, NULL, 0));
Packit Service 3470d1
			} else {
Packit Service 3470d1
				_DBG_ERROR("Too many sids.\n");
Packit Service 3470d1
				return -1;
Packit Service 3470d1
			}
Packit Service 3470d1
			break;
Packit Service 3470d1
		case 'q':
Packit Service 3470d1
			req_queries = strtoul(optarg, NULL, 0);
Packit Service 3470d1
			if (req_queries == ULONG_MAX) {
Packit Service 3470d1
				_DBG_ERROR("Invalid req_queries arg: %s", optarg);
Packit Service 3470d1
				return -1;
Packit Service 3470d1
			}
Packit Service 3470d1
			break;
Packit Service 3470d1
		default:
Packit Service 3470d1
			usage(argv);
Packit Service 3470d1
			return -1;
Packit Service 3470d1
		}
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	if (optind >= argc) {
Packit Service 3470d1
		usage(argv);
Packit Service 3470d1
		return -1;
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	f=fopen(argv[optind], "r");
Packit Service 3470d1
	if (f == NULL) {
Packit Service 3470d1
		fprintf(stderr, "Failed to open guid file (%s)\n",
Packit Service 3470d1
			argv[optind]);
Packit Service 3470d1
		return -1; 
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	numsources = get_sources();
Packit Service 3470d1
	if (numsources < 0) {
Packit Service 3470d1
		fprintf(stderr, "Could not read source port data.\n");
Packit Service 3470d1
		fclose(f);
Packit Service 3470d1
		return -1;
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	hfi = op_path_find_hfi("",&device);
Packit Service 3470d1
	if (!hfi || !device) {
Packit Service 3470d1
		fprintf(stderr,"Could not open HFI.\n");
Packit Service 3470d1
		fclose(f);
Packit Service 3470d1
		return -1;
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	context = op_path_open(device, port);
Packit Service 3470d1
	if (!context) {
Packit Service 3470d1
		fprintf(stderr, "Could not open path interface.\n");
Packit Service 3470d1
		goto failopen;
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	dest_ports = malloc(sizeof(record) * numdests);
Packit Service 3470d1
	if (!dest_ports) {
Packit Service 3470d1
		fprintf(stderr, "Could not allocate memory for destinations.\n");
Packit Service 3470d1
		goto failmalloc;
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
	i=0;
Packit Service 3470d1
	while (!readrecord(f, &dest_ports[i])) {
Packit Service 3470d1
		i++;
Packit Service 3470d1
		if (i >= numdests) {
Packit Service 3470d1
			numdests = numdests * 2;
Packit Service 3470d1
			dest_ports = realloc(dest_ports, numdests * sizeof(record));
Packit Service 3470d1
			if (!dest_ports) {
Packit Service 3470d1
				fprintf(stderr, "Could not allocate memory for destinations.\n");
Packit Service 3470d1
				goto failmalloc;
Packit Service 3470d1
			}
Packit Service 3470d1
		}
Packit Service 3470d1
	}
Packit Service 3470d1
		
Packit Service 3470d1
	numdests = i;
Packit Service 3470d1
	_DBG_NOTICE("Read %u destinations and %u sources.\n",
Packit Service 3470d1
			numdests, numsources);
Packit Service 3470d1
	if (numsources == 0 || numdests == 0) goto fail;
Packit Service 3470d1
Packit Service 3470d1
	falsepos = falseneg = queries = passes = 0;
Packit Service 3470d1
	
Packit Service 3470d1
	gettimeofday(&start_time, NULL);
Packit Service 3470d1
	
Packit Service 3470d1
	srand48(start_time.tv_sec);
Packit Service 3470d1
Packit Service 3470d1
	do {
Packit Service 3470d1
		unsigned j;
Packit Service 3470d1
Packit Service 3470d1
		for (j=0; j
Packit Service 3470d1
			op_path_rec_t query, response;
Packit Service 3470d1
			int d = j; //lrand48() % numdests;
Packit Service 3470d1
			int s = lrand48() % numsources;
Packit Service 3470d1
			int lid_query = 0;
Packit Service 3470d1
Packit Service 3470d1
			memset(&query,0,sizeof(query));
Packit Service 3470d1
Packit Service 3470d1
			lid_query = lrand48() % 2;
Packit Service 3470d1
			if (lid_query) {
Packit Service 3470d1
				unsigned lmc_offset = 
Packit Service 3470d1
					lrand48()%src_ports[s].num_lids;
Packit Service 3470d1
				query.slid = htons(
Packit Service 3470d1
				   ntohs(src_ports[s].base_lid) + lmc_offset);
Packit Service 3470d1
				query.dlid = htons(
Packit Service 3470d1
				   ntohs(dest_ports[d].lid) + lmc_offset);
Packit Service 3470d1
			} else {
Packit Service 3470d1
				query.sgid.unicast.prefix = 
Packit Service 3470d1
					src_ports[s].prefix;
Packit Service 3470d1
				query.sgid.unicast.interface_id = 
Packit Service 3470d1
					src_ports[s].guid;
Packit Service 3470d1
				query.dgid.unicast.prefix = 
Packit Service 3470d1
					src_ports[s].prefix;
Packit Service 3470d1
				query.dgid.unicast.interface_id = 
Packit Service 3470d1
					dest_ports[d].guid;
Packit Service 3470d1
			}
Packit Service 3470d1
			if (numpkeys) query.pkey = 
Packit Service 3470d1
				pkey[lrand48() % numpkeys];
Packit Service 3470d1
			if (numsids) query.service_id = 
Packit Service 3470d1
				sid[lrand48() % numsids];
Packit Service 3470d1
Packit Service 3470d1
			queries++;
Packit Service 3470d1
			err = op_path_get_path_by_rec(context, &query, 
Packit Service 3470d1
						      &response);
Packit Service 3470d1
			if ((err != 0) && (dest_ports[d].disable == 0) &&
Packit Service 3470d1
				(src_ports[s].disable == 0)) {
Packit Service 3470d1
					falseneg++;
Packit Service 3470d1
					if (lid_query) 
Packit Service 3470d1
						dest_ports[d].lid_fail_count++;
Packit Service 3470d1
					else
Packit Service 3470d1
						dest_ports[d].guid_fail_count++;
Packit Service 3470d1
Packit Service 3470d1
			} else if ((err == 0) && 
Packit Service 3470d1
				   ((dest_ports[d].disable != 0) ||
Packit Service 3470d1
				    (src_ports[s].disable != 0))) {
Packit Service 3470d1
					falsepos++;
Packit Service 3470d1
					if (lid_query) 
Packit Service 3470d1
						dest_ports[d].lid_fail_count++;
Packit Service 3470d1
					else
Packit Service 3470d1
						dest_ports[d].guid_fail_count++;
Packit Service 3470d1
			} else if (lid_query) {
Packit Service 3470d1
				dest_ports[d].lid_fail_count = 0;
Packit Service 3470d1
			} else {
Packit Service 3470d1
				dest_ports[d].guid_fail_count = 0;
Packit Service 3470d1
			}
Packit Service 3470d1
		}
Packit Service 3470d1
Packit Service 3470d1
		passes++;
Packit Service 3470d1
	} while (queries < req_queries);
Packit Service 3470d1
Packit Service 3470d1
	gettimeofday(&end_time, NULL);
Packit Service 3470d1
	timersub(&end_time, &start_time, &elapsed_time);
Packit Service 3470d1
	_DBG_PRINT("%lu queries, %lu false negatives, %lu false positives\n"
Packit Service 3470d1
		   "%lu passes, elapsed time %ld sec %ld usec.\n",
Packit Service 3470d1
		   queries, falseneg, falsepos, passes, elapsed_time.tv_sec,
Packit Service 3470d1
		   elapsed_time.tv_usec);
Packit Service 3470d1
	if (elapsed_time.tv_sec > 1) {
Packit Service 3470d1
		perf = queries * 1000 /  (elapsed_time.tv_sec * 1000 + 
Packit Service 3470d1
					  elapsed_time.tv_usec /1000);
Packit Service 3470d1
		_DBG_PRINT("Perf: %lu queries/sec.\n", perf);
Packit Service 3470d1
	}
Packit Service 3470d1
Packit Service 3470d1
fail:
Packit Service 3470d1
	free(dest_ports);
Packit Service 3470d1
failmalloc:
Packit Service 3470d1
	op_path_close(context);
Packit Service 3470d1
failopen:
Packit Service 3470d1
	ibv_close_device(hfi);
Packit Service 3470d1
	fclose(f);
Packit Service 3470d1
	return 0;
Packit Service 3470d1
}