From: Don Slutz <[email protected]>

Signed-off-by: Don Slutz <[email protected]>
---
 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

--
Crash-utility mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility

Reply via email to