summaryrefslogtreecommitdiffstats
path: root/lib/libkvm
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2017-02-09 11:26:48 -0200
committerRenato Botelho <renato@netgate.com>2017-02-09 11:26:48 -0200
commit4a05f5440acda223e6a0ec5157bc32ecc0f09ff9 (patch)
tree4c2ece480e5d4155ed35bec62996de40eb179f18 /lib/libkvm
parent681a482d8fc4bfc14a24f7a9d75cca6337f2a520 (diff)
parenta1e52233c91fd46e666297270ab655f1abff8535 (diff)
downloadFreeBSD-src-4a05f5440acda223e6a0ec5157bc32ecc0f09ff9.zip
FreeBSD-src-4a05f5440acda223e6a0ec5157bc32ecc0f09ff9.tar.gz
Merge remote-tracking branch 'origin/stable/10' into devel
Diffstat (limited to 'lib/libkvm')
-rw-r--r--lib/libkvm/kvm.c54
-rw-r--r--lib/libkvm/kvm.h8
-rw-r--r--lib/libkvm/kvm_getswapinfo.36
-rw-r--r--lib/libkvm/kvm_getswapinfo.c6
-rw-r--r--lib/libkvm/kvm_private.h1
5 files changed, 59 insertions, 16 deletions
diff --git a/lib/libkvm/kvm.c b/lib/libkvm/kvm.c
index 9181a49..85f50ad 100644
--- a/lib/libkvm/kvm.c
+++ b/lib/libkvm/kvm.c
@@ -198,8 +198,10 @@ _kvm_open(kvm_t *kd, const char *uf, const char *mf, int flag, char *errout)
return (kd);
}
}
+
/*
- * This is a crash dump.
+ * This is either a crash dump or a remote live system with its physical
+ * memory fully accessible via a special device.
* Initialize the virtual address translation machinery,
* but first setup the namelist fd.
*/
@@ -207,8 +209,11 @@ _kvm_open(kvm_t *kd, const char *uf, const char *mf, int flag, char *errout)
_kvm_syserr(kd, kd->program, "%s", uf);
goto failed;
}
- if (strncmp(mf, _PATH_FWMEM, strlen(_PATH_FWMEM)) == 0)
+ if (strncmp(mf, _PATH_FWMEM, strlen(_PATH_FWMEM)) == 0 ||
+ strncmp(mf, _PATH_DEVVMM, strlen(_PATH_DEVVMM)) == 0) {
kd->rawdump = 1;
+ kd->writable = 1;
+ }
if (_kvm_initvtop(kd) < 0)
goto failed;
return (kd);
@@ -557,6 +562,15 @@ ssize_t
kvm_write(kvm_t *kd, u_long kva, const void *buf, size_t len)
{
int cc;
+ ssize_t cw;
+ off_t pa;
+ const char *cp;
+
+ if (!ISALIVE(kd) && !kd->writable) {
+ _kvm_err(kd, kd->program,
+ "kvm_write not implemented for dead kernels");
+ return (-1);
+ }
if (ISALIVE(kd)) {
/*
@@ -574,10 +588,36 @@ kvm_write(kvm_t *kd, u_long kva, const void *buf, size_t len)
} else if ((size_t)cc < len)
_kvm_err(kd, kd->program, "short write");
return (cc);
- } else {
- _kvm_err(kd, kd->program,
- "kvm_write not implemented for dead kernels");
- return (-1);
}
- /* NOTREACHED */
+
+ cp = buf;
+ while (len > 0) {
+ cc = _kvm_kvatop(kd, kva, &pa);
+ if (cc == 0)
+ return (-1);
+ if (cc > (ssize_t)len)
+ cc = len;
+ errno = 0;
+ if (lseek(kd->pmfd, pa, 0) == -1 && errno != 0) {
+ _kvm_syserr(kd, 0, _PATH_MEM);
+ break;
+ }
+ cw = write(kd->pmfd, cp, cc);
+ if (cw < 0) {
+ _kvm_syserr(kd, kd->program, "kvm_write");
+ break;
+ }
+ /*
+ * If ka_kvatop returns a bogus value or our core file is
+ * truncated, we might wind up seeking beyond the end of the
+ * core file in which case the read will return 0 (EOF).
+ */
+ if (cw == 0)
+ break;
+ cp += cw;
+ kva += cw;
+ len -= cw;
+ }
+
+ return (cp - (char *)buf);
}
diff --git a/lib/libkvm/kvm.h b/lib/libkvm/kvm.h
index d697795..6c2b102 100644
--- a/lib/libkvm/kvm.h
+++ b/lib/libkvm/kvm.h
@@ -58,11 +58,11 @@ struct proc;
struct kvm_swap {
char ksw_devname[32];
- int ksw_used;
- int ksw_total;
+ u_int ksw_used;
+ u_int ksw_total;
int ksw_flags;
- int ksw_reserved1;
- int ksw_reserved2;
+ u_int ksw_reserved1;
+ u_int ksw_reserved2;
};
#define SWIF_DEV_PREFIX 0x0002
diff --git a/lib/libkvm/kvm_getswapinfo.3 b/lib/libkvm/kvm_getswapinfo.3
index edd2068..bb4e67e 100644
--- a/lib/libkvm/kvm_getswapinfo.3
+++ b/lib/libkvm/kvm_getswapinfo.3
@@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 22, 1999
+.Dd January 2, 2017
.Dt KVM_SWAPINFO 3
.Os
.Sh NAME
@@ -78,9 +78,9 @@ This structure contains the following fields:
.It
.Va char ksw_devname[] ;
.It
-.Va int ksw_total ;
+.Va u_int ksw_total ;
.It
-.Va int ksw_used ;
+.Va u_int ksw_used ;
.It
.Va int ksw_flags ;
.El
diff --git a/lib/libkvm/kvm_getswapinfo.c b/lib/libkvm/kvm_getswapinfo.c
index d79d70c..7d9c8a9 100644
--- a/lib/libkvm/kvm_getswapinfo.c
+++ b/lib/libkvm/kvm_getswapinfo.c
@@ -112,7 +112,8 @@ int
kvm_getswapinfo_kvm(kvm_t *kd, struct kvm_swap *swap_ary, int swap_max,
int flags)
{
- int i, ttl;
+ int i;
+ swblk_t ttl;
TAILQ_HEAD(, swdevt) swtailq;
struct swdevt *sp, swinfo;
struct kvm_swap tot;
@@ -157,7 +158,8 @@ int
kvm_getswapinfo_sysctl(kvm_t *kd, struct kvm_swap *swap_ary, int swap_max,
int flags)
{
- int ti, ttl;
+ int ti;
+ swblk_t ttl;
size_t mibi, len;
int soid[SWI_MAXMIB];
struct xswdev xsd;
diff --git a/lib/libkvm/kvm_private.h b/lib/libkvm/kvm_private.h
index b3eeea7..c47eb07 100644
--- a/lib/libkvm/kvm_private.h
+++ b/lib/libkvm/kvm_private.h
@@ -62,6 +62,7 @@ struct __kvm {
*/
struct vmstate *vmst;
int rawdump; /* raw dump format */
+ int writable; /* physical memory is writable */
int vnet_initialized; /* vnet fields set up */
uintptr_t vnet_start; /* start of kernel's vnet region */
OpenPOWER on IntegriCloud