Add thread number ID to appropriate network commands

The client doesn't necessarily have a 1:1 mapping between jobs
and its internal job representation, so allow it to tell the
various jobs apart.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/client.c b/client.c
index 678a627..6230a66 100644
--- a/client.c
+++ b/client.c
@@ -628,10 +628,11 @@
 {
 	int i, j;
 
-	dst->error	= le32_to_cpu(src->error);
-	dst->groupid	= le32_to_cpu(src->groupid);
-	dst->pid	= le32_to_cpu(src->pid);
-	dst->members	= le32_to_cpu(src->members);
+	dst->error		= le32_to_cpu(src->error);
+	dst->thread_number	= le32_to_cpu(src->thread_number);
+	dst->groupid		= le32_to_cpu(src->groupid);
+	dst->pid		= le32_to_cpu(src->pid);
+	dst->members		= le32_to_cpu(src->members);
 
 	for (i = 0; i < 2; i++) {
 		convert_io_stat(&dst->clat_stat[i], &src->clat_stat[i]);
@@ -719,6 +720,7 @@
 	sum_group_stats(&client_gs, &p->rs);
 
 	client_ts.members++;
+	client_ts.thread_number = p->ts.thread_number;
 	client_ts.groupid = p->ts.groupid;
 
 	if (++sum_stat_nr == sum_stat_clients) {
@@ -981,6 +983,7 @@
 
 	total = nr_samples * sizeof(struct io_sample);
 	ret = malloc(total + sizeof(*pdu));
+	ret->thread_number = le32_to_cpu(pdu->thread_number);
 	ret->nr_samples = nr_samples;
 	ret->log_type = le32_to_cpu(pdu->log_type);
 	strcpy((char *) ret->name, (char *) pdu->name);
diff --git a/fio.h b/fio.h
index db0e875..6e11754 100644
--- a/fio.h
+++ b/fio.h
@@ -66,8 +66,8 @@
 	void *eo;
 	char verror[FIO_VERROR_SIZE];
 	pthread_t thread;
-	int thread_number;
-	int groupid;
+	unsigned int thread_number;
+	unsigned int groupid;
 	struct thread_stat ts;
 
 	int client_type;
diff --git a/gfio.c b/gfio.c
index be0a4ac..7dcb188 100644
--- a/gfio.c
+++ b/gfio.c
@@ -1461,6 +1461,7 @@
 	sum_group_stats(&client_gs, &p->rs);
 
 	client_ts.members++;
+	client_ts.thread_number = p->ts.thread_number;
 	client_ts.groupid = p->ts.groupid;
 
 	if (++sum_stat_nr == sum_stat_clients) {
@@ -1788,6 +1789,8 @@
 	struct gui_entry *ge = gc->ge;
 	char tmp[8];
 
+	p->thread_number = le32_to_cpu(p->thread_number);
+	p->groupid = le32_to_cpu(p->groupid);
 	convert_thread_options_to_cpu(o, &p->top);
 
 	gdk_threads_enter();
diff --git a/init.c b/init.c
index 820c30c..d4a4f33 100644
--- a/init.c
+++ b/init.c
@@ -861,7 +861,7 @@
 	if (!terse_output) {
 		if (!job_add_num) {
 			if (is_backend && !recursed)
-				fio_server_send_add_job(&td->o, td->io_ops->name);
+				fio_server_send_add_job(td);
 
 			if (!strcmp(td->io_ops->name, "cpuio")) {
 				log_info("%s: ioengine=cpu, cpuload=%u,"
diff --git a/server.c b/server.c
index 9110707..899b230 100644
--- a/server.c
+++ b/server.c
@@ -752,10 +752,11 @@
 	strcpy(p.ts.verror, ts->verror);
 	strcpy(p.ts.description, ts->description);
 
-	p.ts.error	= cpu_to_le32(ts->error);
-	p.ts.groupid	= cpu_to_le32(ts->groupid);
-	p.ts.pid	= cpu_to_le32(ts->pid);
-	p.ts.members	= cpu_to_le32(ts->members);
+	p.ts.error		= cpu_to_le32(ts->error);
+	p.ts.thread_number	= cpu_to_le32(ts->thread_number);
+	p.ts.groupid		= cpu_to_le32(ts->groupid);
+	p.ts.pid		= cpu_to_le32(ts->pid);
+	p.ts.members		= cpu_to_le32(ts->members);
 
 	for (i = 0; i < 2; i++) {
 		convert_io_stat(&p.ts.clat_stat[i], &ts->clat_stat[i]);
@@ -910,6 +911,7 @@
 	void *out_pdu;
 	int i, ret = 0;
 
+	pdu.thread_number = cpu_to_le32(td->thread_number);
 	pdu.nr_samples = __cpu_to_le32(log->nr_samples);
 	pdu.log_type = cpu_to_le32(log->log_type);
 	strcpy((char *) pdu.name, name);
@@ -979,12 +981,14 @@
 	return ret;
 }
 
-void fio_server_send_add_job(struct thread_options *o, const char *ioengine)
+void fio_server_send_add_job(struct thread_data *td)
 {
 	struct cmd_add_job_pdu pdu;
 
 	memset(&pdu, 0, sizeof(pdu));
-	convert_thread_options_to_net(&pdu.top, o);
+	pdu.thread_number = cpu_to_le32(td->thread_number);
+	pdu.groupid = cpu_to_le32(td->groupid);
+	convert_thread_options_to_net(&pdu.top, &td->o);
 
 	fio_net_send_cmd(server_fd, FIO_NET_CMD_ADD_JOB, &pdu, sizeof(pdu), 0);
 }
diff --git a/server.h b/server.h
index 27e5523..3c66ecb 100644
--- a/server.h
+++ b/server.h
@@ -38,7 +38,7 @@
 };
 
 enum {
-	FIO_SERVER_VER			= 12,
+	FIO_SERVER_VER			= 13,
 
 	FIO_SERVER_MAX_FRAGMENT_PDU	= 1024,
 
@@ -119,6 +119,8 @@
 };
 
 struct cmd_add_job_pdu {
+	uint32_t thread_number;
+	uint32_t groupid;
 	struct thread_options_pack top;
 };
 
@@ -131,6 +133,7 @@
 };
 
 struct cmd_iolog_pdu {
+	uint32_t thread_number;
 	uint32_t nr_samples;
 	uint32_t log_type;
 	uint8_t name[FIO_NET_NAME_MAX];
@@ -161,9 +164,7 @@
 extern struct fio_net_cmd *fio_net_recv_cmd(int sk);
 
 extern int fio_send_iolog(struct thread_data *, struct io_log *, const char *);
-
-struct thread_options;
-extern void fio_server_send_add_job(struct thread_options *, const char *);
+extern void fio_server_send_add_job(struct thread_data *);
 
 extern int exit_backend;
 extern int fio_net_port;
diff --git a/stat.c b/stat.c
index 8b032b8..70f9e0a 100644
--- a/stat.c
+++ b/stat.c
@@ -956,6 +956,11 @@
 			else
 				memset(ts->description, 0, FIO_JOBNAME_SIZE);
 
+			/*
+			 * If multiple entries in this group, this is
+			 * the first member.
+			 */
+			ts->thread_number = td->thread_number;
 			ts->groupid = td->groupid;
 
 			/*
diff --git a/stat.h b/stat.h
index 0847246..ce640d9 100644
--- a/stat.h
+++ b/stat.h
@@ -118,6 +118,7 @@
 	char name[FIO_JOBNAME_SIZE];
 	char verror[FIO_VERROR_SIZE];
 	uint32_t error;
+	uint32_t thread_number;
 	uint32_t groupid;
 	uint32_t pid;
 	char description[FIO_JOBNAME_SIZE];