Mulai pelacakan PID proses yang salah - tidak respawning

11

Saya awalnya mengajukan pertanyaan ini di StackOverflow. Kemudian menyadari bahwa ini mungkin tempat yang lebih baik.

Saya memiliki pengaturan bluepill untuk memantau proses delay_job saya. (Aplikasi Ruby On Rails)

Menggunakan Ubuntu 12.10.

Saya memulai dan memantau layanan bluepill itu sendiri menggunakan Ubuntu upstart. Konfigurasi pemula saya di bawah ( /etc/init/bluepill.conf).

description "Start up the bluepill service"

start on runlevel [2]
stop on runlevel [016]

expect daemon
exec sudo /home/deploy/.rvm/wrappers/<app_name>/bluepill load /home/deploy/websites/<app_name>/current/config/server/staging/delayed_job.bluepill

# Restart the process if it dies with a signal
# or exit code not given by the 'normal exit' stanza.
respawn

Saya juga sudah mencoba dengan expect forkbukan expect daemon. Saya juga mencoba menghapus expect...garis sepenuhnya.

Saat mesin dinyalakan, bluepill mulai menyala dengan baik.

$ ps aux | grep blue
root      1154  0.6  0.8 206416 17372 ?        Sl   21:19   0:00 bluepilld: <app_name>

PID dari proses bluepill adalah 1154 di sini. Tapi upstartsepertinya melacak PID yang salah. Ini melacak PID yang tidak ada.

$ initctl status bluepill
bluepill start/running, process 990

Saya pikir ini melacak PID dari sudoproses yang memulai proses bluepill.

Ini mencegah proses bluepill dari respawned jika saya secara paksa membunuh bluepill menggunakan kill -9.

Selain itu, saya pikir karena PID yang salah dilacak, reboot / shutdown hanya hang dan saya harus mengatur ulang mesin setiap kali.

Apa yang bisa menjadi masalah di sini?

PEMBARUAN :

Masalahnya masih ada sampai hari ini (3 Mei 2015) di Ubuntu 14.04.2.

Masalahnya bukan karena menggunakan sudo. Saya tidak menggunakan sudo lagi. Konfigurasi pemula baru saya adalah:

description "Start up the bluepill service"

start on runlevel [2]
stop on runlevel [016]

# Restart the process if it dies with a signal
# or exit code not given by the 'normal exit' stanza.
respawn

# Give up if restart occurs 10 times in 90 seconds.
respawn limit 10 90

expect daemon

script
    shared_path=/home/deploy/websites/some_app/shared

    bluepill load $shared_path/config/delayed_job.bluepill
end script

Saat mesin melakukan boot, program memuat dengan baik. Tetapi pemula masih melacak PID yang salah, seperti dijelaskan di atas.

Solusi yang disebutkan dalam komentar dapat memperbaiki masalah menggantung. Saya belum mencobanya.

Anjan
sumber
Sudahkah Anda mencoba melihat proses 990? ps aux | grep 990harus melakukannya tetapi pstree 990mungkin lebih informatif.
Oli
Tidak ada proses dengan PID 990.
Anjan
2
sejauh kebutuhan untuk reboot untuk mendapatkan kembali baru ke keadaan baik - lihat alat yang bagus ini: github.com/ion1/workaround-upstart-snafu
andersonbd1
dan Anda dapat mempercepat alat itu dengan perintah ini: $ echo 3000 | sudo tee / proc / sys / kernel / pid_max
andersonbd1

Jawaban:

8

Cukup terlambat, tapi mudah-mudahan ini bisa membantu pengguna lain.

Ada bug yang didokumentasikan di pemula yang dapat menyebabkan initctl untuk melacak PID yang salah jika Anda menentukan forkbait yang salah di konfigurasi pemula: https://bugs.launchpad.net/upstart/+bug/406397

Apa yang terjadi adalah bahwa pemula memeriksa forkbait dan menentukan berapa banyak proses bercabang yang harus diperiksa sebelum memilih PID "benar" dari program yang sedang dikontrol. Jika Anda menentukan expect forkatau expect daemontetapi program Anda tidak membayar beberapa kali, startakan hang. Jika, di sisi lain, proses Anda terlalu banyak bercabang, initctlakan melacak PID yang salah. Secara teoritis, ini harus didokumentasikan di bagian buku masak pemula ini , tetapi seperti yang Anda lihat dalam situasi ini ada PID yang terkait dengan proses pembunuhan ketika seharusnya tidak ada.

Implikasi dari hal ini dijelaskan dalam komentar bugtracker, tapi saya akan meringkas di sini: selain initctltidak dapat menghentikan proses daemon dan terjebak dalam keadaan tidak berdokumen / ilegal <service> start/killed, process <pid>, jika proses milik PID itu berhenti (dan biasanya akan ) maka PID dibebaskan untuk digunakan kembali oleh sistem.

Jika Anda mengeluarkan initctl stop <service>atau service <service> stop, initctlakan membunuh PID itu saat muncul berikutnya. Ini berarti bahwa, di suatu tempat di jalan jika Anda tidak me-reboot setelah membuat kesalahan ini, proses selanjutnya untuk menggunakan PID akan segera dibunuh oleh initctlmeskipun itu bukan daemon. Ini bisa berupa sesuatu yang sesederhana catatau serumit itu ffmpeg, dan Anda akan kesulitan mencari tahu mengapa paket perangkat lunak Anda macet di tengah beberapa operasi rutin.

Jadi, masalahnya adalah Anda menentukan expectopsi yang salah untuk jumlah garpu yang sebenarnya dibuat oleh proses daemon Anda. Mereka mengatakan ada penulisan ulang pemula yang membahas masalah ini, tetapi pada pemula 1,8 (Ubuntu 13.04 / Januari 2014 terbaru) masalah ini masih ada.

Karena Anda menggunakan expect daemondan berakhir dengan masalah ini, saya sarankan mencoba expect fork.

Sunting: Berikut adalah skrip yang kompatibel dengan Ubuntu BASH ( asli oleh Wade Fitzpatrick dimodifikasi untuk menggunakan Ubuntu sleep) yang memunculkan proses sampai ruang proses alamat ID yang tersedia habis, pada titik mana itu dimulai kembali pada 0 dan bekerja hingga "macet" PID. Suatu proses kemudian melahirkan di PID initctldigantung, dan initctlmembunuhnya dan me-reset.

#!/bin/bash

# usage: sh /tmp/upstart_fix.sh <pid>

sleep 0.001 &
firstPID=$!
#first lets exhaust the space
while (( $! >= $firstPID ))
do
    sleep 0.001 &
done

# [ will use testPID itself, we want to use the next pid
declare -i testPID
testPID=$(($1 - 1))
while (( $! < $testPID ))
do
    sleep 0.001 &
done

# fork a background process then die so init reaps its pid
sleep 3 &
echo "Init will reap PID=$!"
kill -9 $$
# EOF
Dakota
sumber
Jawaban ini memiliki beberapa informasi yang berguna dan menarik tetapi tidak jelas bagi saya bagaimana jawaban ini menjawab pertanyaan awal seperti @Anjan menyebutkan "Saya juga mencoba dengan fork fork alih-alih mengharapkan daemon. Saya juga telah mencoba menghapus garis ...
user12345
5

Untuk contoh yang diberikan:

$ initctl status bluepill
bluepill start/running, process 990

solusi cepat untuk saya adalah:

# If upstart gets stuck for some job in stop/killed state
export PID=990
cd /usr/local/bin
wget https://raw.github.com/ion1/workaround-upstart-snafu/master/workaround-upstart-snafu
chmod +x workaround-upstart-snafu
./workaround-upstart-snafu $PID

sumber: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=582745#37

Saya berharap ini akan membantu. Apa yang terjadi dijelaskan dalam jawaban lain.

Szymon Jeż
sumber
Naskah yang bagus. Ini bisa memakan waktu satu atau dua menit. Sebuah rebootkadang-kadang mungkin lebih disukai dan juga perbaikan ini.
Peter Ilfrich
0

Kecuali jika Anda menjalankan pekerjaan tingkat pengguna pemula atau menggunakan bait setuid - maka pekerjaan Anda berjalan sebagai root.

Karena Pemula sudah berjalan sebagai root, mengapa Anda perlu menggunakan sudo sama sekali dalam execbait Anda ?

Menggunakan sudoatau sudalam execbait telah menyebabkan masalah yang sama bagi saya seperti yang Anda jelaskan di sini.

Biasanya saya akan mengalami item 1 ATAU keduanya 1 DAN 2:

  1. pemula mengikuti PID yang salah
  2. pemula mulai hang ketika saya mencoba untuk menghentikan proses

Tentu saja, selain itu Anda harus memiliki expectbait yang mencerminkan jumlah garpu yang benar.

YMMV, tetapi untuk saya:

  • menggunakan sudo atau su dalam execbait dengan jumlah garpu yang benar secara umum menghasilkan situasi 1 di atas.
  • jumlah garpu yang ditentukan salah (dengan sudo / su kami dalam exec) menghasilkan situasi 1 DAN 2 di atas.
pengguna12345
sumber