From: Don Slutz <dslutz(a)verizon.com>
Signed-off-by: Don Slutz <dslutz(a)verizon.com>
---
defs.h | 1 +
remote.c | 241 +++++++++++++++++++++++++++++++++++++++++++++------------------
2 files changed, 173 insertions(+), 69 deletions(-)
diff --git a/defs.h b/defs.h
index a5299cc..108ffc1 100755
--- a/defs.h
+++ b/defs.h
@@ -504,6 +504,7 @@ struct program_context {
#define GET_LOG (0x200ULL)
#define VMCOREINFO (0x400ULL)
#define ALLOW_FP (0x800ULL)
+#define REMOTE_NIL (0x1000ULL)
char *cleanup;
char *namelist_orig;
char *namelist_debug_orig;
diff --git a/remote.c b/remote.c
index fca08a1..e64f2bd 100755
--- a/remote.c
+++ b/remote.c
@@ -1808,6 +1808,10 @@ static int remote_file_type(char *);
static int remote_lkcd_dump_init(void);
static int remote_s390_dump_init(void);
static int remote_netdump_init(void);
+static int remote_tcp_read(int, const char *, size_t);
+static int remote_tcp_read_string(int, const char *, size_t, int);
+static int remote_tcp_write(int, const void *, size_t);
+static int remote_tcp_write_string(int, const char *);
/*
* Parse, verify and establish a connection with the network daemon
@@ -1921,6 +1925,16 @@ is_remote_daemon(char *dp)
remote_socket_options(pc->sockfd);
+ /*
+ * Try and use NIL mode.
+ */
+ BZERO(sendbuf, BUFSIZE);
+ BZERO(recvbuf, BUFSIZE);
+ sprintf(sendbuf, "NIL");
+ remote_tcp_write_string(pc->sockfd, sendbuf);
+ remote_tcp_read_string(pc->sockfd, recvbuf, BUFSIZE-1, 0);
+ if (!strstr(recvbuf, "<FAIL>"))
+ pc->flags2 |= REMOTE_NIL;
/*
* Get the remote machine type and verify a match. The daemon pid
* is also used as a live system initial context.
@@ -1928,8 +1942,8 @@ is_remote_daemon(char *dp)
BZERO(sendbuf, BUFSIZE);
BZERO(recvbuf, BUFSIZE);
sprintf(sendbuf, "MACHINE_PID");
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
- recv(pc->sockfd, recvbuf, BUFSIZE-1, 0);
+ remote_tcp_write_string(pc->sockfd, sendbuf);
+ remote_tcp_read_string(pc->sockfd, recvbuf, BUFSIZE-1, pc->flags2 &
REMOTE_NIL);
p1 = strtok(recvbuf, " "); /* MACHINE */
p1 = strtok(NULL, " "); /* machine type */
if (CRASHDEBUG(1))
@@ -2032,8 +2046,8 @@ remote_file_type(char *file)
BZERO(sendbuf, BUFSIZE);
BZERO(recvbuf, BUFSIZE);
sprintf(sendbuf, "TYPE %s", file);
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
- recv(pc->sockfd, recvbuf, BUFSIZE-1, 0);
+ remote_tcp_write_string(pc->sockfd, sendbuf);
+ remote_tcp_read_string(pc->sockfd, recvbuf, BUFSIZE-1, pc->flags2 &
REMOTE_NIL);
if (strstr(recvbuf, "<FAIL>"))
error(FATAL, "invalid remote file name: %s\n", file);
@@ -2112,6 +2126,84 @@ remote_socket_options(int sockfd)
}
/*
+ * Wrapper around recv to read full length packet.
+ */
+static int
+remote_tcp_read(int sock, const char *pv_buffer, size_t cb_buffer)
+{
+ size_t cb_total = 0;
+
+ do
+ {
+ ssize_t cb_read = recv(sock, (void*)pv_buffer, cb_buffer, MSG_NOSIGNAL);
+
+ if (cb_read <= 0)
+ return cb_read;
+ cb_total += cb_read;
+ cb_buffer -= cb_read;
+ pv_buffer = (char *)pv_buffer + cb_read;
+ } while (cb_buffer);
+
+ return cb_total;
+}
+
+/*
+ * Wrapper around recv to read full string packet.
+ */
+static int
+remote_tcp_read_string(int sock, const char *pv_buffer, size_t cb_buffer, int nil_mode)
+{
+ size_t cb_total = 0;
+
+ do
+ {
+ ssize_t cb_read = recv(sock, (void*)pv_buffer, cb_buffer, MSG_NOSIGNAL);
+
+ if (cb_read <= 0)
+ return cb_read;
+ cb_total += cb_read;
+ if (!nil_mode && cb_total >= 4)
+ return cb_total;
+ if (!pv_buffer[cb_read - 1])
+ return cb_total;
+ cb_buffer -= cb_read;
+ pv_buffer = (char *)pv_buffer + cb_read;
+ } while (cb_buffer);
+
+ return cb_total;
+}
+
+/*
+ * Wrapper around send to send full packet.
+ */
+static int
+remote_tcp_write(int sock, const void *pv_buffer, size_t cb_buffer)
+{
+ do
+ {
+ size_t cb_now = cb_buffer;
+ ssize_t cb_written = send(sock, (const char *)pv_buffer, cb_now, MSG_NOSIGNAL);
+
+ if (cb_written < 0)
+ return 1;
+ cb_buffer -= cb_written;
+ pv_buffer = (char *)pv_buffer + cb_written;
+ } while (cb_buffer);
+
+ return 0;
+}
+
+/*
+ * Wrapper around tcp_write to send a string
+ */
+static int
+remote_tcp_write_string(int sock, const char *pv_buffer)
+{
+ return remote_tcp_write(sock, pv_buffer, strlen(pv_buffer) + 1);
+}
+
+
+/*
* Request that the daemon open a file.
*/
static int
@@ -2124,8 +2216,8 @@ remote_file_open(struct remote_file *rfp)
BZERO(sendbuf, BUFSIZE);
BZERO(recvbuf, BUFSIZE);
sprintf(sendbuf, "OPEN %s", rfp->filename);
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
- recv(pc->sockfd, recvbuf, BUFSIZE-1, 0);
+ remote_tcp_write_string(pc->sockfd, sendbuf);
+ remote_tcp_read_string(pc->sockfd, recvbuf, BUFSIZE-1, pc->flags2 &
REMOTE_NIL);
if (CRASHDEBUG(1))
fprintf(fp, "remote_file_open: [%s]\n", recvbuf);
@@ -2159,8 +2251,8 @@ remote_file_close(struct remote_file *rfp)
BZERO(sendbuf, BUFSIZE);
BZERO(recvbuf, BUFSIZE);
sprintf(sendbuf, "CLOSE %d", rfp->fd);
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
- recv(pc->sockfd, recvbuf, BUFSIZE-1, 0);
+ remote_tcp_write_string(pc->sockfd, sendbuf);
+ remote_tcp_read_string(pc->sockfd, recvbuf, BUFSIZE-1, pc->flags2 &
REMOTE_NIL);
return (strstr(recvbuf, "OK") ? TRUE : FALSE);
}
@@ -2177,8 +2269,8 @@ remote_proc_version(char *buf)
BZERO(sendbuf, BUFSIZE);
BZERO(recvbuf, BUFSIZE);
sprintf(sendbuf, "PROC_VERSION");
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
- recv(pc->sockfd, recvbuf, BUFSIZE-1, 0);
+ remote_tcp_write_string(pc->sockfd, sendbuf);
+ remote_tcp_read_string(pc->sockfd, recvbuf, BUFSIZE-1, pc->flags2 &
REMOTE_NIL);
if (STREQ(recvbuf, "<FAIL>"))
return FALSE;
strcpy(buf, recvbuf);
@@ -2359,8 +2451,8 @@ copy_to_local_namelist(struct remote_file *rfp)
BZERO(sendbuf, BUFSIZE);
BZERO(recvbuf, BUFSIZE);
sprintf(sendbuf, "DEBUGGING_SYMBOLS %s", rfp->filename);
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
- recv(pc->sockfd, recvbuf, BUFSIZE-1, 0);
+ remote_tcp_write_string(pc->sockfd, sendbuf);
+ remote_tcp_read_string(pc->sockfd, recvbuf, BUFSIZE-1, pc->flags2 &
REMOTE_NIL);
if (strstr(recvbuf, "NO_DEBUG")) {
sprintf(readbuf, "%s@%s", rfp->filename, pc->server);
pc->namelist = readbuf;
@@ -2472,8 +2564,8 @@ identical_namelist(char *file, struct remote_file *rfp)
BZERO(readbuf, BUFSIZE);
sprintf(sendbuf, "LINUX_VERSION %s", rfp->filename);
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
- recv(pc->sockfd, recvbuf, BUFSIZE-1, 0);
+ remote_tcp_write_string(pc->sockfd, sendbuf);
+ remote_tcp_read_string(pc->sockfd, recvbuf, BUFSIZE-1, pc->flags2 &
REMOTE_NIL);
if (strstr(recvbuf, "<FAIL>"))
return FALSE;
@@ -2515,8 +2607,8 @@ remote_file_checksum(struct remote_file *rfp)
BZERO(sendbuf, BUFSIZE);
BZERO(recvbuf, BUFSIZE);
sprintf(sendbuf, "SUM %s", rfp->filename);
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
- recv(pc->sockfd, recvbuf, BUFSIZE-1, 0);
+ remote_tcp_write_string(pc->sockfd, sendbuf);
+ remote_tcp_read_string(pc->sockfd, recvbuf, BUFSIZE-1, pc->flags2 &
REMOTE_NIL);
if (strstr(recvbuf, "<FAIL>")) {
error(INFO, "%s: does not exist on server %s\n",
rfp->filename, pc->server);
@@ -2785,8 +2877,8 @@ remote_find_booted_kernel(struct remote_file *rfp)
BZERO(sendbuf, BUFSIZE);
BZERO(recvbuf, BUFSIZE);
sprintf(sendbuf, "FIND_BOOTED_KERNEL");
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
- recv(pc->sockfd, recvbuf, BUFSIZE-1, 0);
+ remote_tcp_write_string(pc->sockfd, sendbuf);
+ remote_tcp_read_string(pc->sockfd, recvbuf, BUFSIZE-1, pc->flags2 &
REMOTE_NIL);
strtok(recvbuf, " "); /* FIND_BOOTED_KERNEL */
p1 = strtok(NULL, " "); /* filename */
if (STREQ(p1, "<FAIL>"))
@@ -2806,8 +2898,8 @@ remote_lkcd_dump_init(void)
BZERO(sendbuf, BUFSIZE);
BZERO(recvbuf, BUFSIZE);
sprintf(sendbuf, "LKCD_DUMP_INIT %d %s", pc->rmfd,
pc->server_memsrc);
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
- recv(pc->sockfd, recvbuf, BUFSIZE-1, 0);
+ remote_tcp_write_string(pc->sockfd, sendbuf);
+ remote_tcp_read_string(pc->sockfd, recvbuf, BUFSIZE-1, pc->flags2 &
REMOTE_NIL);
if (strstr(recvbuf, "<FAIL>"))
return FALSE;
@@ -2844,8 +2936,8 @@ remote_s390_dump_init(void)
BZERO(sendbuf, BUFSIZE);
BZERO(recvbuf, BUFSIZE);
sprintf(sendbuf, "S390_DUMP_INIT %d %s", pc->rmfd,
pc->server_memsrc);
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
- recv(pc->sockfd, recvbuf, BUFSIZE-1, 0);
+ remote_tcp_write_string(pc->sockfd, sendbuf);
+ remote_tcp_read_string(pc->sockfd, recvbuf, BUFSIZE-1, pc->flags2 &
REMOTE_NIL);
if (strstr(recvbuf, "<FAIL>"))
return FALSE;
@@ -2880,8 +2972,8 @@ remote_netdump_init(void)
BZERO(sendbuf, BUFSIZE);
BZERO(recvbuf, BUFSIZE);
sprintf(sendbuf, "NETDUMP_INIT %d %s", pc->rmfd,
pc->server_memsrc);
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
- recv(pc->sockfd, recvbuf, BUFSIZE-1, 0);
+ remote_tcp_write_string(pc->sockfd, sendbuf);
+ remote_tcp_read_string(pc->sockfd, recvbuf, BUFSIZE-1, pc->flags2 &
REMOTE_NIL);
if (strstr(recvbuf, "<FAIL>"))
return FALSE;
@@ -2925,8 +3017,8 @@ remote_page_size(void)
error(FATAL,
"cannot determine remote page size (unknown memory source)\n");
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
- recv(pc->sockfd, recvbuf, BUFSIZE-1, 0);
+ remote_tcp_write_string(pc->sockfd, sendbuf);
+ remote_tcp_read_string(pc->sockfd, recvbuf, BUFSIZE-1, pc->flags2 &
REMOTE_NIL);
if (strstr(recvbuf, "FAIL"))
error(FATAL, "cannot determine remote page size\n");
strtok(recvbuf, " "); /* PAGESIZE */
@@ -2968,7 +3060,7 @@ copy_remote_file(struct remote_file *rfp, int fd, char *file, char
*ttystr)
BZERO(sendbuf, BUFSIZE);
sprintf(sendbuf, "READ %d %lx %ld", rfp->fd, offset, size);
- bytes = write(pc->sockfd, sendbuf, strlen(sendbuf));
+ bytes = write(pc->sockfd, sendbuf, strlen(sendbuf) + 1);
bzero(readbuf, READBUFSIZE);
@@ -3059,7 +3151,7 @@ copy_remote_gzip_file(struct remote_file *rfp, char *file, char
*ttystr)
BZERO(sendbuf, BUFSIZE);
sprintf(sendbuf, "READ_GZIP %ld %s", pc->rcvbufsize,
rfp->filename);
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
+ remote_tcp_write_string(pc->sockfd, sendbuf);
bzero(readbuf, READBUFSIZE);
@@ -3170,8 +3262,8 @@ find_remote_module_objfile(struct load_module *lm, char *module,
char *retbuf)
BZERO(recvbuf, BUFSIZE);
sprintf(sendbuf, "FIND_MODULE %s %s",
kt->utsname.release, module);
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
- recv(pc->sockfd, recvbuf, BUFSIZE-1, 0);
+ remote_tcp_write_string(pc->sockfd, sendbuf);
+ remote_tcp_read_string(pc->sockfd, recvbuf, BUFSIZE-1, pc->flags2 &
REMOTE_NIL);
if (strstr(recvbuf, "<FAIL>")) {
fprintf(fp, "find_remote_module_objfile: [%s]\n",
recvbuf);
@@ -3231,8 +3323,8 @@ remote_free_memory(void)
BZERO(sendbuf, BUFSIZE);
BZERO(recvbuf, BUFSIZE);
sprintf(sendbuf, "MEMORY FREE %s", type);
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
- recv(pc->sockfd, recvbuf, BUFSIZE-1, 0);
+ remote_tcp_write_string(pc->sockfd, sendbuf);
+ remote_tcp_read_string(pc->sockfd, recvbuf, BUFSIZE-1, pc->flags2 &
REMOTE_NIL);
p1 = strtok(recvbuf, " "); /* MEMORY */
p1 = strtok(NULL, " "); /* FREE */
p1 = strtok(NULL, " "); /* MCLXCD, LKCD etc. */
@@ -3267,8 +3359,8 @@ remote_memory_used(void)
BZERO(sendbuf, BUFSIZE);
BZERO(recvbuf, BUFSIZE);
sprintf(sendbuf, "MEMORY USED %s", type);
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
- recv(pc->sockfd, recvbuf, BUFSIZE-1, 0);
+ remote_tcp_write_string(pc->sockfd, sendbuf);
+ remote_tcp_read_string(pc->sockfd, recvbuf, BUFSIZE-1, pc->flags2 &
REMOTE_NIL);
p1 = strtok(recvbuf, " "); /* MEMORY */
p1 = strtok(NULL, " "); /* FREE */
p1 = strtok(NULL, " "); /* MCLXCD, LKCD, etc. */
@@ -3308,7 +3400,7 @@ remote_memory_dump(int verbose)
BZERO(sendbuf, BUFSIZE);
sprintf(sendbuf, "MEMORY_DUMP %ld %s%s", pc->rcvbufsize, type,
verbose ? "_VERBOSE" : "");
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
+ remote_tcp_write_string(pc->sockfd, sendbuf);
bzero(readbuf, READBUFSIZE);
done = total = 0;
@@ -3371,10 +3463,9 @@ int
remote_memory_read(int rfd, char *buffer, int cnt, physaddr_t address)
{
char sendbuf[BUFSIZE];
- char readbuf[READBUFSIZE];
char datahdr[DATA_HDRSIZE];
- char *bufptr, *p1;
- int ret, req, tot;
+ char *p1;
+ int ret, tot;
ulong addr;
addr = (ulong)address; /* may be virtual */
@@ -3391,48 +3482,49 @@ remote_memory_read(int rfd, char *buffer, int cnt, physaddr_t
address)
else
sprintf(sendbuf, "READ_LIVE %d %lx %d", rfd, addr, cnt);
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
-
- bzero(readbuf, READBUFSIZE);
+ if (remote_tcp_write_string(pc->sockfd, sendbuf))
+ return -1;
/*
* Read request will come back with a singular header
* followed by the data.
*/
- req = cnt+DATA_HDRSIZE;
- tot = 0;
- errno = 0;
- bufptr = readbuf;
-
- while (req) {
- if ((ret = recv(pc->sockfd, bufptr, req, 0)) == -1)
- return -1;
- req -= ret;
- bufptr += ret;
- tot += ret;
- if ((tot >= DATA_HDRSIZE) && STRNEQ(readbuf, FAILMSG)) {
- p1 = strtok(readbuf, " "); /* FAIL */
- p1 = strtok(NULL, " "); /* errno */
- errno = atoi(p1);
- return -1;
- }
+ BZERO(datahdr, DATA_HDRSIZE);
+ ret = remote_tcp_read_string(pc->sockfd, datahdr, DATA_HDRSIZE, 1);
+ if (ret <= 0)
+ return -1;
+ if (CRASHDEBUG(3))
+ fprintf(fp, "remote_memory_read: [%s]\n", datahdr);
+ if (STRNEQ(datahdr, FAILMSG)) {
+ p1 = strtok(datahdr, " "); /* FAIL */
+ p1 = strtok(NULL, " "); /* errno */
+ errno = atoi(p1);
+ return -1;
}
-
- if (!STRNEQ(readbuf, DONEMSG) && !STRNEQ(readbuf, DATAMSG)) {
+ if (!STRNEQ(datahdr, DONEMSG) && !STRNEQ(datahdr, DATAMSG)) {
error(INFO, "out of sync with remote memory source\n");
return -1;
}
- strncpy(datahdr, readbuf, DATA_HDRSIZE);
- if (CRASHDEBUG(3))
- fprintf(fp, "remote_memory_read: [%s]\n", datahdr);
- p1 = strtok(datahdr, " "); /* DONE */
- p1 = strtok(NULL, " "); /* count */
+ p1 = strtok(datahdr, " "); /* DONE */
+ p1 = strtok(NULL, " "); /* count */
tot = atol(p1);
- BCOPY(readbuf+DATA_HDRSIZE, buffer, tot);
+ if (cnt != tot) {
+ error(FATAL,
+ "requested %d bytes remote memory return %d bytes\n",
+ cnt, tot);
+ return -1;
+ }
+ ret = remote_tcp_read(pc->sockfd, buffer, tot);
+ if (ret != tot) {
+ error(FATAL,
+ "requested %d bytes remote memory return %d bytes\n",
+ ret, tot);
+ return -1;
+ }
return tot;
}
@@ -3492,7 +3584,7 @@ remote_execute(void)
BZERO(sendbuf, BUFSIZE);
sprintf(sendbuf, "EXECUTE %ld %s", pc->rcvbufsize, command);
- send(pc->sockfd, sendbuf, strlen(sendbuf), 0);
+ remote_tcp_write_string(pc->sockfd, sendbuf);
bzero(readbuf, READBUFSIZE);
done = total = 0;
@@ -3561,12 +3653,23 @@ remote_exit(void)
BZERO(buf, BUFSIZE);
sprintf(buf, "EXIT");
- send(pc->sockfd, buf, strlen(buf), 0);
+ remote_tcp_write_string(pc->sockfd, buf);
/*
* Read but ignore the return status -- we don't really care...
*/
- recv(pc->sockfd, buf, BUFSIZE-1, 0);
+ remote_tcp_read_string(pc->sockfd, buf, BUFSIZE-1, pc->flags2 &
REMOTE_NIL);
}
#endif /* !DAEMON */
+/*
+ * Specify Emacs local variables so the formating
+ * of the code stays the same.
+ *
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 8
+ * indent-tabs-mode: t
+ * End:
+ */
--
1.8.4