diff mbox

[RESEND] Remove 16-character limit on process title

Message ID 20101105163549.GA12049@boost.horde.net
State New
Headers show

Commit Message

John Morrissey Nov. 5, 2010, 4:35 p.m. UTC
qemu uses prctl() to set its process title. I bumped up against prctl()'s
16-character limit recently, when adding process title support to
libvirt[1][2].

The attached patch overwrites argv instead. Linux seems to maintain the
length of the original args, even when the new args are shorter and
NULL-terminated, so the trailing whitespace in ps(1) output is probably
unavoidable. I've seen the same result with other daemons that overwrite
argv.

john

[1] https://www.redhat.com/archives/libvir-list/2010-October/msg00565.html
[2] http://libvirt.org/git/?p=libvirt.git;a=commit;h=c08c7b0143b8cdc542e5f4137623d412340c5cf2

Comments

Andreas Färber Nov. 7, 2010, 2:24 p.m. UTC | #1
Hello,

Am 05.11.2010 um 17:35 schrieb John Morrissey:

> qemu uses prctl() to set its process title. I bumped up against  
> prctl()'s
> 16-character limit recently, when adding process title support to
> libvirt[1][2].
>
> The attached patch overwrites argv instead. Linux seems to maintain  
> the
> length of the original args, even when the new args are shorter and
> NULL-terminated, so the trailing whitespace in ps(1) output is  
> probably
> unavoidable. I've seen the same result with other daemons that  
> overwrite
> argv.

Please use git-send-email to send it inline along with a commit  
message, so that it can be better reviewed and applied.
Also lacks a Signed-off-by. Please see CODING_STYLE or list archives.

Andreas

>
> john
>
> [1] https://www.redhat.com/archives/libvir-list/2010-October/msg00565.html
> [2] http://libvirt.org/git/?p=libvirt.git;a=commit;h=c08c7b0143b8cdc542e5f4137623d412340c5cf2
> -- 
> John Morrissey          _o            /\         ----  __o
> jwm@horde.net        _-< \_          /  \       ----  <  \,
> www.horde.net/    __(_)/_(_)________/    \_______(_) /_(_)__
> <qemu-remove-process-title-length-limit.patch>
Anthony Liguori Nov. 16, 2010, 3:34 p.m. UTC | #2
On 11/05/2010 11:35 AM, John Morrissey wrote:
> qemu uses prctl() to set its process title. I bumped up against prctl()'s
> 16-character limit recently, when adding process title support to
> libvirt[1][2].
>
> The attached patch overwrites argv instead. Linux seems to maintain the
> length of the original args, even when the new args are shorter and
> NULL-terminated, so the trailing whitespace in ps(1) output is probably
> unavoidable. I've seen the same result with other daemons that overwrite
> argv.
>
> john
>
> [1] https://www.redhat.com/archives/libvir-list/2010-October/msg00565.html
> [2] http://libvirt.org/git/?p=libvirt.git;a=commit;h=c08c7b0143b8cdc542e5f4137623d412340c5cf2
>    

Needs a Signed-off-by.

Regards,

Anthony Liguori
diff mbox

Patch

diff --git a/os-posix.c b/os-posix.c
index 6321e99..4d85384 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -39,10 +39,6 @@ 
 #include "net/slirp.h"
 #include "qemu-options.h"
 
-#ifdef CONFIG_LINUX
-#include <sys/prctl.h>
-#endif
-
 static struct passwd *user_pwd;
 static const char *chroot_dir;
 static int daemonize;
@@ -145,20 +141,24 @@  char *os_find_datadir(const char *argv0)
 #undef SHARE_SUFFIX
 #undef BUILD_SUFFIX
 
-void os_set_proc_name(const char *s)
+void os_set_proc_name(int argc, char **argv, const char *name)
 {
-#if defined(PR_SET_NAME)
-    char name[16];
-    if (!s)
+#ifdef CONFIG_LINUX
+    char *last_argv_byte, *p;
+    int len, i;
+
+    if (!name)
         return;
-    name[sizeof(name) - 1] = 0;
-    strncpy(name, s, sizeof(name));
-    /* Could rewrite argv[0] too, but that's a bit more complicated.
-       This simple way is enough for `top'. */
-    if (prctl(PR_SET_NAME, name)) {
-        perror("unable to change process name");
-        exit(1);
-    }
+
+    last_argv_byte = argv[argc - 1] + strlen(argv[argc - 1]);
+
+    len = snprintf(argv[0], last_argv_byte - argv[0], "%s", name);
+
+    p = &argv[0][len];
+    while (p <= last_argv_byte)
+        *p++ = '\0';
+    for (i = 1; i < argc; ++i)
+        argv[i] = (char *) "";
 #else
     fprintf(stderr, "Change of process name not supported by your OS\n");
     exit(1);
diff --git a/qemu-os-posix.h b/qemu-os-posix.h
index ed5c058..b2e3b6a 100644
--- a/qemu-os-posix.h
+++ b/qemu-os-posix.h
@@ -31,7 +31,7 @@  static inline void os_host_main_loop_wait(int *timeout)
 }
 
 void os_set_line_buffering(void);
-void os_set_proc_name(const char *s);
+void os_set_proc_name(int argc, char **argv, const char *name);
 void os_setup_signal_handling(void);
 void os_daemonize(void);
 void os_setup_post(void);
diff --git a/qemu-os-win32.h b/qemu-os-win32.h
index c63778d..9653992 100644
--- a/qemu-os-win32.h
+++ b/qemu-os-win32.h
@@ -46,7 +46,8 @@  static inline void os_setup_signal_handling(void) {}
 static inline void os_daemonize(void) {}
 static inline void os_setup_post(void) {}
 void os_set_line_buffering(void);
-static inline void os_set_proc_name(const char *dummy) {}
+static inline void os_set_proc_name(int argc, char **argv,
+                                    const char *dummy) {}
 
 #if !defined(EPROTONOSUPPORT)
 # define EPROTONOSUPPORT EINVAL
diff --git a/vl.c b/vl.c
index df414ef..b82b0e8 100644
--- a/vl.c
+++ b/vl.c
@@ -1799,7 +1799,11 @@  static const QEMUOption *lookup_opt(int argc, char **argv,
         optarg = NULL;
     }
 
-    *poptarg = optarg;
+    if (optarg != NULL) {
+        *poptarg = qemu_strdup(optarg);
+    } else {
+        *poptarg = NULL;
+    }
     *poptind = optind;
 
     return popt;
@@ -1827,6 +1831,7 @@  int main(int argc, char **argv, char **envp)
     int tb_size;
     const char *pid_file = NULL;
     const char *incoming = NULL;
+    const char *process_name = NULL;
     int show_vnc_port = 0;
     int defconfig = 1;
 
@@ -2528,7 +2533,7 @@  int main(int argc, char **argv, char **envp)
 			    exit(1);
 			}
 			p += 8;
-			os_set_proc_name(p);
+			process_name = p;
 		     }	
 		 }	
                 break;
@@ -2754,6 +2759,8 @@  int main(int argc, char **argv, char **envp)
         exit(1);
     }
 
+    os_set_proc_name(argc, argv, process_name);
+
     if (kvm_allowed) {
         int ret = kvm_init(smp_cpus);
         if (ret < 0) {