Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Jul 2013 09:34:08 +0300
From:      Mikolaj Golub <to.my.trociny@gmail.com>
To:        Jilles Tjoelker <jilles@stack.nl>
Cc:        freebsd-arch@freebsd.org, Robert Millan <rmh@freebsd.org>
Subject:   Re: ABI change in libkvm (kvm_uread removal)
Message-ID:  <20130710063406.GA39842@gmail.com>
In-Reply-To: <20130709211657.GA86400@stack.nl>
References:  <CAOfDtXPT-BQt9aqTNYHRK0XdiqKZsPnsO6s9vei=XCpyBvZZ6w@mail.gmail.com> <20130709185846.GA19508@gmail.com> <20130709211657.GA86400@stack.nl>

next in thread | previous in thread | raw e-mail | index | archive | help

--oyUTqETQ0mS9luUI
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Tue, Jul 09, 2013 at 11:16:57PM +0200, Jilles Tjoelker wrote:
> On Tue, Jul 09, 2013 at 09:59:19PM +0300, Mikolaj Golub wrote:
> > Suggestions how this should be fixed properly (if possible) are highly
> > appreciated. I will do what people suggest.
> 
> I would suggest bringing back kvm_uread() in stable/9 so that the ABI is
> kept. In head, I suggest removing kvm_uread() from the header file and
> bumping the soname. I think MFCing the soname bump will cause more
> annoyance than the removal of kvm_uread() itself.
> 
> Much of the code using libkvm uses it to access kernel internals, which
> are not a proper ABI/API and change fairly frequently. Therefore, it is
> probably acceptable for this library not to use symbol versioning.
> 
> The functions that do not expose the caller to kernel internals like
> kvm_getprocs() should probably not be used; instead, libprocstat
> provides a more ABI-stable way to do the same. Calling the sysctls
> directly is also an option.

Thank you all for your suggestions. I like Jilles' the most. So I am
going to return kvm_uread back to stable/9 by a direct commit and
remove it entirely from head and bump soname.

-- 
Mikolaj Golub

--oyUTqETQ0mS9luUI
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: inline; filename="libkvm.kvm_uread.all.1.patch"

Index: head/ObsoleteFiles.inc
===================================================================
--- head/ObsoleteFiles.inc	(revision 253133)
+++ head/ObsoleteFiles.inc	(working copy)
@@ -38,6 +38,9 @@
 #   xargs -n1 | sort | uniq -d;
 # done
 
+# 20130710: libkvm version bump 
+OLD_LIBS+=lib/libkvm.so.5
+OLD_LIBS+=usr/lib32/libkvm.so.5
 # 20130623: dialog update from 1.1 to 1.2
 OLD_LIBS+=usr/lib/libdialog.so.7
 OLD_LIBS+=usr/lib32/libdialog.so.7
Index: head/lib/libkvm/Makefile
===================================================================
--- head/lib/libkvm/Makefile	(revision 253133)
+++ head/lib/libkvm/Makefile	(working copy)
@@ -3,6 +3,7 @@
 
 LIB=	kvm
 SHLIBDIR?= /lib
+SHLIB_MAJOR=	6
 CFLAGS+=-DLIBC_SCCS -I${.CURDIR}
 
 .if exists(${.CURDIR}/kvm_${MACHINE_ARCH}.c)
Index: head/lib/libkvm/kvm.h
===================================================================
--- head/lib/libkvm/kvm.h	(revision 253133)
+++ head/lib/libkvm/kvm.h	(working copy)
@@ -89,8 +89,6 @@ kvm_t	 *kvm_openfiles
 	    (const char *, const char *, const char *, int, char *);
 ssize_t	  kvm_read(kvm_t *, unsigned long, void *, size_t);
 ssize_t	  kvm_read_zpcpu(kvm_t *, void *, u_long, size_t, int);
-ssize_t	  kvm_uread
-	    (kvm_t *, const struct kinfo_proc *, unsigned long, char *, size_t);
 ssize_t	  kvm_write(kvm_t *, unsigned long, const void *, size_t);
 __END_DECLS
 
Index: stable/9/lib/libkvm/kvm_proc.c
===================================================================
--- stable/9/lib/libkvm/kvm_proc.c	(revision 253133)
+++ stable/9/lib/libkvm/kvm_proc.c	(working copy)
@@ -712,3 +712,55 @@ kvm_getenvv(kvm_t *kd, const struct kinfo_proc *kp
 {
 	return (kvm_argv(kd, kp, 1, nchr));
 }
+
+/*
+ * Read from user space.  The user context is given by p.
+ */
+ssize_t
+kvm_uread(kvm_t *kd, const struct kinfo_proc *kp, u_long uva, char *buf,
+	size_t len)
+{
+	char *cp;
+	char procfile[MAXPATHLEN];
+	ssize_t amount;
+	int fd;
+
+	if (!ISALIVE(kd)) {
+		_kvm_err(kd, kd->program,
+		    "cannot read user space from dead kernel");
+		return (0);
+	}
+
+	sprintf(procfile, "/proc/%d/mem", kp->ki_pid);
+	fd = open(procfile, O_RDONLY, 0);
+	if (fd < 0) {
+		_kvm_err(kd, kd->program, "cannot open %s", procfile);
+		return (0);
+	}
+
+	cp = buf;
+	while (len > 0) {
+		errno = 0;
+		if (lseek(fd, (off_t)uva, 0) == -1 && errno != 0) {
+			_kvm_err(kd, kd->program, "invalid address (%lx) in %s",
+			    uva, procfile);
+			break;
+		}
+		amount = read(fd, cp, len);
+		if (amount < 0) {
+			_kvm_syserr(kd, kd->program, "error reading %s",
+			    procfile);
+			break;
+		}
+		if (amount == 0) {
+			_kvm_err(kd, kd->program, "EOF reading %s", procfile);
+			break;
+		}
+		cp += amount;
+		uva += amount;
+		len -= amount;
+	}
+
+	close(fd);
+	return ((ssize_t)(cp - buf));
+}

--oyUTqETQ0mS9luUI--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130710063406.GA39842>