Blob Blame History Raw
From: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
Subject: KVM: make pid available for uevents without debugfs
Patch-mainline: v4.13-rc3
Git-commit: fdeaf7e3eb37c6dbc4b4ac97dbe1945d239eb788
References: FATE#323770,bsc#1061982

Summary:     kernel: Report distro KVM using Call Home
Description: This patch adds a few lines to the KVM common code to fire
             a KOBJ_CHANGE uevent whenever a KVM VM is created or
             destroyed. The event carries five environment variables:

             CREATED indicates how many times a new VM has been created.
                 It is useful for example to trigger specific actions
                 when the first VM is started
             COUNT indicates how many VMs are currently active. This can
                 be used for logging or monitoring purposes
             PID has the pid of the KVM process that has been started or
                 stopped. This can be used to perform process-specific
                 tuning.
             STATS_PATH contains the path in debugfs to the directory
                 with all the runtime statistics for this VM. This is
                 useful for performance monitoring and profiling.
             EVENT described the type of event, its value can be either
                 "create" or "destroy"

             Specific udev rules can be then set up in userspace to deal
             with the creation or destruction of VMs as needed.

Upstream-Description:

             KVM: make pid available for uevents without debugfs

             Simplify and improve the code so that the PID is always available in
             the uevent even when debugfs is not available.

             This adds a userspace_pid field to struct kvm, as per Radim's
             suggestion, so that the PID can be retrieved on destruction too.

             Acked-by: Janosch Frank <frankja@linux.vnet.ibm.com>
             Fixes: 286de8f6ac9202 ("KVM: trigger uevents when creating or destroying a VM")
             Signed-off-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
             Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>


Signed-off-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
Acked-by: Hannes Reinecke <hare@suse.com>
---
 include/linux/kvm_host.h |    1 +
 virt/kvm/kvm_main.c      |   33 +++++++++++----------------------
 2 files changed, 12 insertions(+), 22 deletions(-)

--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -438,6 +438,7 @@ struct kvm {
 	struct kvm_stat_data **debugfs_stat_data;
 	struct srcu_struct srcu;
 	struct srcu_struct irq_srcu;
+	pid_t userspace_pid;
 };
 
 #define kvm_err(fmt, ...) \
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -3859,7 +3859,6 @@ static const struct file_operations *sta
 static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm)
 {
 	struct kobj_uevent_env *env;
-	char *tmp, *pathbuf = NULL;
 	unsigned long long created, active;
 
 	if (!kvm_dev.this_device || !kvm)
@@ -3883,38 +3882,28 @@ static void kvm_uevent_notify_change(uns
 	add_uevent_var(env, "CREATED=%llu", created);
 	add_uevent_var(env, "COUNT=%llu", active);
 
-	if (type == KVM_EVENT_CREATE_VM)
+	if (type == KVM_EVENT_CREATE_VM) {
 		add_uevent_var(env, "EVENT=create");
-	else if (type == KVM_EVENT_DESTROY_VM)
+		kvm->userspace_pid = task_pid_nr(current);
+	} else if (type == KVM_EVENT_DESTROY_VM) {
 		add_uevent_var(env, "EVENT=destroy");
+	}
+	add_uevent_var(env, "PID=%d", kvm->userspace_pid);
 
 	if (kvm->debugfs_dentry) {
-		char p[ITOA_MAX_LEN];
+		char *tmp, *p = kmalloc(PATH_MAX, GFP_KERNEL);
 
-		snprintf(p, sizeof(p), "%s", kvm->debugfs_dentry->d_name.name);
-		tmp = strchrnul(p + 1, '-');
-		*tmp = '\0';
-		add_uevent_var(env, "PID=%s", p);
-		pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
-		if (pathbuf) {
-			/* sizeof counts the final '\0' */
-			int len = sizeof("STATS_PATH=") - 1;
-			const char *pvar = "STATS_PATH=";
-
-			tmp = dentry_path_raw(kvm->debugfs_dentry,
-					      pathbuf + len,
-					      PATH_MAX - len);
-			if (!IS_ERR(tmp)) {
-				memcpy(tmp - len, pvar, len);
-				env->envp[env->envp_idx++] = tmp - len;
-			}
+		if (p) {
+			tmp = dentry_path_raw(kvm->debugfs_dentry, p, PATH_MAX);
+			if (!IS_ERR(tmp))
+				add_uevent_var(env, "STATS_PATH=%s", tmp);
+			kfree(p);
 		}
 	}
 	/* no need for checks, since we are adding at most only 5 keys */
 	env->envp[env->envp_idx++] = NULL;
 	kobject_uevent_env(&kvm_dev.this_device->kobj, KOBJ_CHANGE, env->envp);
 	kfree(env);
-	kfree(pathbuf);
 }
 
 static int kvm_init_debug(void)