cleanup -daemonize and pidfile creation a bit
cover cleanup -daemonize and pidfile creation a bit
The $subject theme is quite messy, with many things done in a cryptic and twisty way without any need for that. This trivial patch series tries to clean up and improve it. In particular, it aims to make pidfile errors visible with -daemonize -- something which Gonglei tried to fix in e5048d15ce6a and which we're revering because that fix turned out to be incomplete and wrong.
The patches are simple but I split them into several to easy review.
Michael Tokarev (4):
os-posix: use global daemon_pipe instead of cryptic fds[1]
os-posix: replace goto again with a proper loop
pidfile: stop making pidfile error a special case
os-posix: reorder parent notification for -daemonize
include/qemu-common.h | 1 - os-posix.c | 62 ++++++++++++++++++------------------------------- os-win32.c | 5 ---- vl.c | 2 +- 4 files changed, 23 insertions(+), 47 deletions(-)
Signature · 1 line
1.7.10.4
PATCH 1/4 os-posix: use global daemon_pipe instead of cryptic fds[1]
When asked to -daemonize, we fork a child and setup a pipe between it and parent to pass exit status. os-posix.c used global fds[2] array for that, but actually only the writing side of the pipe is needed to be global, and this name is really too generic. Use just one interger for the writing side of the pipe, and name it daemon_pipe to be more understandable than cryptic fds[1].
--- os-posix.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
os-posix.c +6 -4
@@ -47,7 +47,7 @@static struct passwd *user_pwd;static const char *chroot_dir;static int daemonize; -static int fds[2 ]; +static int daemon_pipe;void os_setup_early_signal_handling (void ) {
@@ -205,6 +205,7 @@ void os_daemonize(void) {if (daemonize) {pid_t pid; +int fds[2 ];if (pipe (fds) ==-1 ) {exit (1 );
@@ -236,7 +237,8 @@ void os_daemonize(void) }close (fds[0 ]); -qemu_set_cloexec (fds[1 ]); + daemon_pipe = fds[1 ]; +qemu_set_cloexec (daemon_pipe);setsid ();
@@ -263,7 +265,7 @@ void os_setup_post(void)ssize_t len; again1: - len =write (fds[1 ], &status,1 ); + len =write (daemon_pipe, &status,1 );if (len ==-1 && (errno ==EINTR )) { goto again1; }
@@ -296,7 +298,7 @@ void os_pidfile_error(void) {if (daemonize) {uint8_t status =1 ; -if (write (fds[1 ], &status,1 ) !=1 ) { +if (write (daemon_pipe, &status,1 ) !=1 ) {perror ("daemonize. Writing to pipe\n" ); } }else
Signature · 1 line
1.7.10.4
Re: [Qemu-devel] [PATCH 1/4] os-posix: use global daemon_pipe instead of cryptic fds[1]
Quoted 11 lines · Michael Tokarev
When asked to -daemonize, we fork a child and setup a pipe between it and parent to pass exit status.
os-posix.cused global fds[2] array for that, but actually only the writing side of the pipe is needed to be global, and this name is really too generic. Use just one interger for the writing side of the pipe, and name itdaemon_pipeto be more understandable than cryptic fds[1].Signed-off-by Michael Tokarev <[email protected]>--- os-posix.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
Best regards,
-Gonglei
PATCH 2/4 os-posix: replace goto again with a proper loop
In reply to Michael TokarevElminiate two fullwrite implementations with goto replacing them with a proper do..while loop.
--- os-posix.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-)
os-posix.c +6 -10
@@ -218,11 +218,9 @@ void os_daemonize(void)close (fds[1 ]); - again: - len =read (fds[0 ], &status,1 ); -if (len ==-1 && (errno ==EINTR )) { - goto again; - } +do { + len =read (fds[0 ], &status,1 ); + }while (len <0 && errno ==EINTR );if (len !=1 ) {exit (1 ); }
@@ -264,11 +262,9 @@ void os_setup_post(void)uint8_t status =0 ;ssize_t len; - again1: - len =write (daemon_pipe, &status,1 ); -if (len ==-1 && (errno ==EINTR )) { - goto again1; - } +do { + len =write (daemon_pipe, &status,1 ); + }while (len <0 && errno ==EINTR );if (len !=1 ) {exit (1 ); }
Signature · 1 line
1.7.10.4
Re: [Qemu-devel] [PATCH 2/4] os-posix: replace goto again with a proper loop
Quoted 1 line · Michael Tokarev
Elminiate two fullwrite implementations with goto replacing them with
s/Elminiate/Eliminate/
Quoted 6 lines
a proper do..while loop.
Signed-off-by Michael Tokarev <[email protected]>--- os-posix.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-)
Best regards,
-Gonglei
PATCH 3/4 pidfile: stop making pidfile error a special case
In reply to Michael TokarevIn case of -daemonize, we write non-zero to the daemon pipe only if pidfile creation failed, so the parent will report error about pidfile problem. There's no need to make special case for this, since all other errors are reported by the child just fine. Let the parent report error and simplify logic in os_daemonize().
This way, we don't need os_pidfile_error() function, since it only prints error now, so put the error reporting printf into the only place where qemu_create_pidfile() is called, in vl.c.
While at it, fix wrong identation in os_daemonize().
--- include/qemu-common.h | 1 - os-posix.c | 29 ++++++----------------------- os-win32.c | 5 ----- vl.c | 2 +- 4 files changed, 7 insertions(+), 30 deletions(-)
include/qemu-common.h +0 -1
@@ -357,7 +357,6 @@ char *qemu_find_file(int type, const char *name);void os_setup_early_signal_handling (void );char *os_find_datadir (void );void os_parse_cmd_args (int index,const char *optarg); -void os_pidfile_error (void );/* Convert a byte between binary and BCD. */ static inline uint8_t to_bcd (uint8_t val)
os-posix.c +6 -23
@@ -221,18 +221,12 @@ void os_daemonize(void)do { len =read (fds[0 ], &status,1 ); }while (len <0 && errno ==EINTR ); -if (len !=1 ) { -exit (1 ); - } -else if (status ==1 ) { -fprintf (stderr,"Could not acquire pidfile\n" ); -exit (1 ); - }else { -exit (0 ); - } - }else if (pid <0 ) { -exit (1 ); - } + +exit (len ==1 && status ==0 ?0 :1 ); + + }else if (pid <0 ) { +exit (1 ); + }close (fds[0 ]); daemon_pipe = fds[1 ];
@@ -290,17 +284,6 @@ void os_setup_post(void) } } -void os_pidfile_error (void ) -{ -if (daemonize) { -uint8_t status =1 ; -if (write (daemon_pipe, &status,1 ) !=1 ) { -perror ("daemonize. Writing to pipe\n" ); - } - }else -fprintf (stderr,"Could not acquire pid file: %s\n" ,strerror (errno)); -} -void os_set_line_buffering (void ) {setvbuf (stdout,NULL , _IOLBF,0 );
os-win32.c +0 -5
@@ -104,11 +104,6 @@ void os_parse_cmd_args(int index, const char *optarg)return ; } -void os_pidfile_error (void ) -{ -fprintf (stderr,"Could not acquire pid file: %s\n" ,strerror (errno)); -} -int qemu_create_pidfile (const char *filename) {char buffer[128 ];
vl.c +1 -1
@@ -3999,7 +3999,7 @@ int main(int argc, char **argv, char **envp)#endif if (pid_file &&qemu_create_pidfile (pid_file) !=0 ) { -os_pidfile_error (); +fprintf (stderr,"Could not acquire pid file: %s\n" ,strerror (errno));exit (1 ); }
Signature · 1 line
1.7.10.4
Re: [Qemu-devel] [PATCH 3/4] pidfile: stop making pidfile error a special case
Quoted 7 lines · Michael Tokarev
In case of -daemonize, we write non-zero to the daemon pipe only if pidfile creation failed, so the parent will report error about pidfile problem. There's no need to make special case for this, since all other errors are reported by the child just fine. Let the parent report error and simplify logic in
os_daemonize().
Quoted 6 lines
This way, we don't need
os_pidfile_error()function, since it only prints error now, so put the error reporting printf into the only place whereqemu_create_pidfile()is called, invl.c.While at it, fix wrong identation in
os_daemonize().
s/identation/identification/
Quoted 26 lines
Signed-off-by Michael Tokarev <[email protected]>--- include/qemu-common.h | 1 - os-posix.c | 29 ++++++----------------------- os-win32.c | 5 ----- vl.c | 2 +- 4 files changed, 7 insertions(+), 30 deletions(-)include/qemu-common.h +0
-1@@ -357,7 +357,6 @@ char *qemu_find_file(int type, const char *name);void os_setup_early_signal_handling (void );char *os_find_datadir (void );void os_parse_cmd_args (int index,const char *optarg); -void os_pidfile_error (void );/* Convert a byte between binary and BCD. */ static inline uint8_t to_bcd (uint8_t val)os-posix.c +0
-0
os-posix.c void os_daemonize(void) · line 226
Quoted 6 lines
os-posix.c +0
-3@@ -221,18 +221,12 @@ void os_daemonize(void)do { len =read (fds[0 ], &status,1 ); }while (len <0 && errno ==EINTR ); -if (len !=1 ) { -exit (1 ); - }
Does this check need to be removed?
Quoted 65 lines
os-posix.c +6
-20-else if (status ==1 ) { -fprintf (stderr,"Could not acquire pidfile\n" ); -exit (1 ); - }else { -exit (0 ); - } - }else if (pid <0 ) { -exit (1 ); - } + +exit (len ==1 && status ==0 ?0 :1 ); + + }else if (pid <0 ) { +exit (1 ); + }close (fds[0 ]); daemon_pipe = fds[1 ];@@ -290,17 +284,6 @@ void os_setup_post(void) } } -void os_pidfile_error (void ) -{ -if (daemonize) { -uint8_t status =1 ; -if (write (daemon_pipe, &status,1 ) !=1 ) { -perror ("daemonize. Writing to pipe\n" ); - } - }else -fprintf (stderr,"Could not acquire pid file: %s\n" ,strerror (errno)); -} -void os_set_line_buffering (void ) {setvbuf (stdout,NULL , _IOLBF,0 );os-win32.c +0
-5@@ -104,11 +104,6 @@ void os_parse_cmd_args(int index, const char *optarg)return ; } -void os_pidfile_error (void ) -{ -fprintf (stderr,"Could not acquire pid file: %s\n" ,strerror (errno)); -} -int qemu_create_pidfile (const char *filename) {char buffer[128 ];vl.c +1
-1@@ -3999,7 +3999,7 @@ int main(int argc, char **argv, char **envp)#endif if (pid_file &&qemu_create_pidfile (pid_file) !=0 ) { -os_pidfile_error (); +fprintf (stderr,"Could not acquire pid file: %s\n" ,strerror (errno));exit (1 ); }
Re: [Qemu-devel] [PATCH 3/4] pidfile: stop making pidfile error a special case
Quoted 9 lines · Gonglei
Quoted 7 lines · Michael Tokarev
In case of -daemonize, we write non-zero to the daemon pipe only if pidfile creation failed, so the parent will report error about pidfile problem. There's no need to make special case for this, since all other errors are reported by the child just fine. Let the parent report error and simplify logic in
os_daemonize().
Quoted 8 lines
Quoted 6 lines
This way, we don't need
os_pidfile_error()function, since it only prints error now, so put the error reporting printf into the only place whereqemu_create_pidfile()is called, invl.c.While at it, fix wrong identation in
os_daemonize().s/identation/identification/
No, the original word was the right one.
Quoted 18 lines
Quoted 18 lines
Signed-off-by Michael Tokarev <[email protected]>--- include/qemu-common.h | 1 - os-posix.c | 29 ++++++----------------------- os-win32.c | 5 ----- vl.c | 2 +- 4 files changed, 7 insertions(+), 30 deletions(-)include/qemu-common.h +0
-1@@ -357,7 +357,6 @@ char *qemu_find_file(int type, const char *name);void os_setup_early_signal_handling (void );char *os_find_datadir (void );void os_parse_cmd_args (int index,const char *optarg); -void os_pidfile_error (void );
Quoted 15 lines
os-posix.c void os_daemonize(void) · line 226
Quoted 13 lines
include/qemu-common.h +0
-0/* Convert a byte between binary and BCD. */ static inline uint8_t to_bcd (uint8_t val)os-posix.c +0
-3@@ -221,18 +221,12 @@ void os_daemonize(void)do { len =read (fds[0 ], &status,1 ); }while (len <0 && errno ==EINTR ); -if (len !=1 ) { -exit (1 ); - }Does this check need to be removed?
Yes, because...
Quoted 12 lines
os-posix.c void os_daemonize(void) · line 225
Quoted 12 lines
os-posix.c +2
-9-else if (status ==1 ) { -fprintf (stderr,"Could not acquire pidfile\n" ); -exit (1 ); - }else { -exit (0 ); - } - }else if (pid <0 ) { -exit (1 ); - } + +exit (len ==1 && status ==0 ?0 :1 );
...it is checked here, note the 'len == 1' part of the condition.
And here comes the wrong original identation -- this part of "else" was indented once too many:
Quoted 5 lines
os-posix.c void os_daemonize(void) · line 230
Quoted 5 lines
os-posix.c +4
-0+ + }else if (pid <0 ) { +exit (1 ); + }
Thanks,
/mjt
Re: [Qemu-devel] [PATCH 3/4] pidfile: stop making pidfile error a special case
Quoted 15 lines · Michael Tokarev
Quoted 14 lines · Gonglei
Quoted 12 lines · Michael Tokarev
In case of -daemonize, we write non-zero to the daemon pipe only if pidfile creation failed, so the parent will report error about pidfile problem. There's no need to make special case for this, since all other errors are reported by the child just fine. Let the parent report error and simplify logic in
os_daemonize().This way, we don't need
os_pidfile_error()function, since it only prints error now, so put the error reporting printf into the only place whereqemu_create_pidfile()is called, invl.c.
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
While at it, fix wrong identation in
os_daemonize().s/identation/identification/
No, the original word was the right one.
Sorry, I can't find 'identation' both dictionary and Google. Your meaning 'indentation'?
Quoted 48 lines
Quoted 18 lines
Quoted 18 lines
Signed-off-by Michael Tokarev <[email protected]>--- include/qemu-common.h | 1 - os-posix.c | 29 ++++++----------------------- os-win32.c | 5 ----- vl.c | 2 +- 4 files changed, 7 insertions(+), 30 deletions(-)include/qemu-common.h +0
-1@@ -357,7 +357,6 @@ char *qemu_find_file(int type, const char *name);void os_setup_early_signal_handling (void );char *os_find_datadir (void );void os_parse_cmd_args (int index,const char *optarg); -void os_pidfile_error (void );Quoted 15 lines
os-posix.c void os_daemonize(void) · line 226
Quoted 13 lines
include/qemu-common.h +0
-0/* Convert a byte between binary and BCD. */ static inline uint8_t to_bcd (uint8_t val)os-posix.c +0
-3@@ -221,18 +221,12 @@ void os_daemonize(void)do { len =read (fds[0 ], &status,1 ); }while (len <0 && errno ==EINTR ); -if (len !=1 ) { -exit (1 ); - }Does this check need to be removed?
Yes, because...
Quoted 12 lines
os-posix.c void os_daemonize(void) · line 225
Quoted 12 lines
os-posix.c +2
-9-else if (status ==1 ) { -fprintf (stderr,"Could not acquire pidfile\n" ); -exit (1 ); - }else { -exit (0 ); - } - }else if (pid <0 ) { -exit (1 ); - } + +exit (len ==1 && status ==0 ?0 :1 );
Quoted 2 lines
...it is checked here, note the 'len == 1' part of the condition.
If len != 1, the original code exit with 1, after your changes, it will exit with 0. Right?
Quoted 3 lines
And here comes the wrong original identation -- this part of "else" was indented once too many:
I know your meaning now. :)
Quoted 10 lines
Quoted 5 lines
os-posix.c void os_daemonize(void) · line 230
Quoted 5 lines
os-posix.c +4
-0+ + }else if (pid <0 ) { +exit (1 ); + }Thanks,
/mjt
Re: [Qemu-devel] [PATCH 3/4] pidfile: stop making pidfile error a special case
31.10.2014 10:33, Gonglei wrote:
[]
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
Quoted 1 line
While at it, fix wrong identation in
os_daemonize().s/identation/identification/
No, the original word was the right one.
Sorry, I can't find 'identation' both dictionary and Google. Your meaning 'indentation'?
Damn. I missed that one. It is "indentation" inedeed :) (but not identification).
[]
Quoted 23 lines
Quoted 23 lines
Quoted 8 lines
os-posix.c void os_daemonize(void) · line 226
Quoted 6 lines
do { len = read(fds[0], &status, 1); } while (len < 0 && errno == EINTR);os-posix.c +0
-3-if (len !=1 ) { -exit (1 ); - }Does this check need to be removed?
Yes, because...
Quoted 12 lines
Quoted 12 lines
os-posix.c +2
-9-else if (status ==1 ) { -fprintf (stderr,"Could not acquire pidfile\n" ); -exit (1 ); - }else { -exit (0 ); - } - }else if (pid <0 ) { -exit (1 ); - } + +exit (len ==1 && status ==0 ?0 :1 );
Quoted 4 lines
Quoted 1 line
...it is checked here, note the 'len == 1' part of the condition.
If len != 1, the original code exit with 1, after your changes, it will exit with 0. Right?
with len != 1, the condition 'len == 1 && status == 0 ? 0 : 1' evaluates to 1. Maybe I can add a comment here:
+ /* only exit successfully if our child actually
+ * wrote a one-byte zero to our pipe */
+ exit(len == 1 && status == 0 ? 0 : 1);
See the result at http://git.corpit.ru/?p=qemu.git;a=shortlog;h=refs/heads/trivial-patches-next
Thanks,
/mjt
Re: [Qemu-devel] [PATCH 3/4] pidfile: stop making pidfile error a special case
Quoted 38 lines · Michael Tokarev
31.10.2014 10:33, Gonglei wrote:
[]Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
Quoted 1 line
While at it, fix wrong identation in
os_daemonize().s/identation/identification/
No, the original word was the right one.
Sorry, I can't find 'identation' both dictionary and Google. Your meaning 'indentation'?
Damn. I missed that one. It is "indentation" inedeed :) (but not identification).
[]
Quoted 23 lines
Quoted 23 lines
Quoted 8 lines
os-posix.c void os_daemonize(void) · line 226
Quoted 6 lines
do { len = read(fds[0], &status, 1); } while (len < 0 && errno == EINTR);os-posix.c +0
-3-if (len !=1 ) { -exit (1 ); - }Does this check need to be removed?
Yes, because...
Quoted 12 lines
Quoted 12 lines
os-posix.c +2
-9-else if (status ==1 ) { -fprintf (stderr,"Could not acquire pidfile\n" ); -exit (1 ); - }else { -exit (0 ); - } - }else if (pid <0 ) { -exit (1 ); - } + +exit (len ==1 && status ==0 ?0 :1 );
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
...it is checked here, note the 'len == 1' part of the condition.
If len != 1, the original code exit with 1, after your changes, it will exit with 0. Right?
with len != 1, the condition 'len == 1 && status == 0 ? 0 : 1'
Ok. That's will be great if you can modify it
to "(len == 1 && status == 0 ) ? 0 : 1"
Best regards,
-Gonglei
Quoted 12 lines
evaluates to 1. Maybe I can add a comment here:
(quoted diff) +3
-0+ /* only exit successfully if our child actually + * wrote a one-byte zero to our pipe */ + exit(len == 1 && status == 0 ? 0 : 1);See the result at http://git.corpit.ru/?p=qemu.git;a=shortlog;h=refs/heads/trivial-patches-next
Thanks,
/mjt
Re: [Qemu-devel] [PATCH 3/4] pidfile: stop making pidfile error a special case
Quoted 1 line · Gonglei
On 2014/10/31 15:41, Michael Tokarev wrote:
[]
Quoted 11 lines
Quoted 8 lines
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line
+
exit(len == 1 && status == 0 ? 0 : 1);...it is checked here, note the 'len == 1' part of the condition.
If len != 1, the original code exit with 1, after your changes, it will exit with 0. Right?
with len != 1, the condition 'len == 1 && status == 0 ? 0 : 1'
Ok. That's will be great if you can modify it
to "(len == 1 && status == 0 ) ? 0 : 1"
Well, ? operator has lowest precedence in C, && and || is higher, and == is even higher. That's the basic rules of the language. So I don't really see why... ;)
The comment however should clear all confusion, hopefully.
Quoted 8 lines
Quoted 8 lines
evaluates to 1. Maybe I can add a comment here:
(quoted diff) +3
-0+ /* only exit successfully if our child actually + * wrote a one-byte zero to our pipe */ + exit(len == 1 && status == 0 ? 0 : 1);See the result at http://git.corpit.ru/?p=qemu.git;a=shortlog;h=refs/heads/trivial-patches-next
Re: [Qemu-devel] [PATCH 3/4] pidfile: stop making pidfile error a special case
Quoted 12 lines · Michael Tokarev
Quoted 1 line · Gonglei
On 2014/10/31 15:41, Michael Tokarev wrote:
[]
Quoted 9 lines
Quoted 8 lines
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line
+
exit(len == 1 && status == 0 ? 0 : 1);...it is checked here, note the 'len == 1' part of the condition.
If len != 1, the original code exit with 1, after your changes, it will exit with 0. Right?
with len != 1, the condition 'len == 1 && status == 0 ? 0 : 1'
Quoted 9 lines
Quoted 2 lines
Ok. That's will be great if you can modify it
to "(len == 1 && status == 0 ) ? 0 : 1"Well, ? operator has lowest precedence in C, && and || is higher, and == is even higher. That's the basic rules of the language. So I don't really see why... ;)
The comment however should clear all confusion, hopefully.
Hmm...
BTW, Do you receive mails subscribed form Qemu community? Does the Qemu maillist system crash?
Since yesterday evening, my colleagues and I do not received mails. It's too weird!
Thanks!
-Gonglei
PATCH 4/4 os-posix: reorder parent notification for -daemonize
In reply to Michael TokarevPut "success" parent reporting in os_setup_post() to after all other initializers which may also fail, to the very end, so more possible failure cases are reported properly to the calling process.
--- os-posix.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
os-posix.c +10 -9
@@ -253,15 +253,6 @@ void os_setup_post(void)int fd =0 ;if (daemonize) { -uint8_t status =0 ; -ssize_t len; - -do { - len =write (daemon_pipe, &status,1 ); - }while (len <0 && errno ==EINTR ); -if (len !=1 ) { -exit (1 ); - }if (chdir ("/" )) {perror ("not able to chdir to /" );exit (1 );
@@ -276,11 +267,21 @@ void os_setup_post(void)change_process_uid ();if (daemonize) { +uint8_t status =0 ; +ssize_t len; +dup2 (fd,0 );dup2 (fd,1 );dup2 (fd,2 );close (fd); + +do { + len =write (daemon_pipe, &status,1 ); + }while (len <0 && errno ==EINTR ); +if (len !=1 ) { +exit (1 ); + } } }
Signature · 1 line
1.7.10.4
Re: [Qemu-devel] [PATCH 4/4] os-posix: reorder parent notification for -daemonize
Quoted 9 lines · Michael Tokarev
Put "success" parent reporting in
os_setup_post()to after all other initializers which may also fail, to the very end, so more possible failure cases are reported properly to the calling process.Signed-off-by Michael Tokarev <[email protected]>--- os-posix.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
Best regards,
-Gonglei