[nginx] unnormal pid file
洪志道
hongzhidao at gmail.com
Sat Mar 18 12:38:46 UTC 2017
Hi.
diff -r 4d874b4d82ed src/core/ngx_cycle.c
--- a/src/core/ngx_cycle.c Thu Mar 16 20:38:31 2017 +0300
+++ b/src/core/ngx_cycle.c Fri Mar 17 22:28:54 2017 -0400
@@ -979,39 +979,17 @@
}
-void
-ngx_delete_pidfile(ngx_cycle_t *cycle)
-{
- u_char *name;
- ngx_core_conf_t *ccf;
-
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
ngx_core_module);
-
- name = ngx_new_binary ? ccf->oldpid.data : ccf->pid.data;
-
- if (ngx_delete_file(name) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- ngx_delete_file_n " \"%s\" failed", name);
- }
-}
-
-
-ngx_int_t
-ngx_signal_process(ngx_cycle_t *cycle, char *sig)
+static ngx_pid_t
+ngx_get_filepid(ngx_cycle_t *cycle, ngx_str_t *name)
{
ssize_t n;
ngx_pid_t pid;
ngx_file_t file;
- ngx_core_conf_t *ccf;
u_char buf[NGX_INT64_LEN + 2];
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "signal process started");
-
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
ngx_core_module);
-
ngx_memzero(&file, sizeof(ngx_file_t));
- file.name = ccf->pid;
+ file.name = *name;
file.log = cycle->log;
file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY,
@@ -1020,7 +998,7 @@
if (file.fd == NGX_INVALID_FILE) {
ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
ngx_open_file_n " \"%s\" failed", file.name.data);
- return 1;
+ return -1;
}
n = ngx_read_file(&file, buf, NGX_INT64_LEN + 2, 0);
@@ -1031,7 +1009,7 @@
}
if (n == NGX_ERROR) {
- return 1;
+ return -1;
}
while (n-- && (buf[n] == CR || buf[n] == LF)) { /* void */ }
@@ -1042,6 +1020,55 @@
ngx_log_error(NGX_LOG_ERR, cycle->log, 0,
"invalid PID number \"%*s\" in \"%s\"",
n, buf, file.name.data);
+ return -1;
+ }
+
+ return pid;
+}
+
+
+void
+ngx_delete_pidfile(ngx_cycle_t *cycle)
+{
+ ngx_pid_t pid;
+ ngx_str_t *name;
+ ngx_core_conf_t *ccf;
+
+ ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
ngx_core_module);
+
+ name = ngx_new_binary ? &ccf->oldpid : &ccf->pid;
+
+ pid = ngx_get_filepid(cycle, name);
+ if (pid == -1) {
+ return;
+ }
+
+ if (pid != ngx_pid) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "pidfile has been
changed %P %P",
+ pid, ngx_pid);
+ return;
+ }
+
+ if (ngx_delete_file(name) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
+ ngx_delete_file_n " \"%s\" failed", name->data);
+ }
+}
+
+
+ngx_int_t
+ngx_signal_process(ngx_cycle_t *cycle, char *sig)
+{
+ ngx_pid_t pid;
+ ngx_core_conf_t *ccf;
+
+ ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "signal process started");
+
+ ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
ngx_core_module);
+
+ pid = ngx_get_filepid(cycle, &ccf->pid);
+
+ if (pid == -1) {
return 1;
}
Thanks.
2017-03-18 15:43 GMT+08:00 洪志道 <hongzhidao at gmail.com>:
> Hi.
>
> It's easy to reproduce such problem that
> the master/worker process are running without the pid file.
>
> Step by step:
>
> 1. Start master process.
> > ./objs/nginx
> nginx.pid successfully create with content (23234)
>
> 2. Create an active connection, purpose for prevent previous master exit.
> > telnet 127.1 80
>
> 3. Quit the previous master, and it still alive for a while.
> > kill -QUIT 23234
>
> 4. Start new master process 23361, and the content of nginx.pid is changed
> to 23361
> > ./objs/nginx
> It successfully start because of the listening port is closed by the
> step 3.
>
> 5. Wait for a while, and the nginx.pid is deleted while the old master
> process (23234) completely quit.
>
> Now the master process (23361) is running without nginx.pid.
>
> So, there are two key points:
> 1. Master start, I think there is not problem.
> 2. Master Exit, is it better to add the pid check with the pid file?
>
> Anyway, I think we should guarantee the pid file associates with the
> running process.
>
> src/os/unix/ngx_process_cycle.c
>
> +static ngx_int_t
> +ngx_is_same_pid(ngx_cycle_t *cycle)
> +{
> + return read_pid_from_pidfile. // TODO
> +}
>
> static void
> ngx_master_process_exit(ngx_cycle_t *cycle)
> {
> ngx_uint_t i;
>
> - ngx_delete_pidfile(cycle);
> + if (ngx_is_same_pid(cycle)) {
> + ngx_delete_pidfile(cycle);
> +
> + } else {
> + ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "blalala...");
> + }
>
> Thanks.
> B.R.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20170318/d8f2ec18/attachment.html>
More information about the nginx-devel
mailing list