Est-il possible de suspendre un processus en cours d'exécution sur des systèmes Linux et de le reprendre plus tard?

38

Je dois copier des fichiers sur une machine. Et les données sont immenses. Maintenant, les serveurs doivent servir normalement, et il y a généralement une plage d'heures occupées. Existe-t-il donc un moyen d'exécuter de telles commandes de manière à interrompre le processus si le serveur est surchargé, puis à le reprendre lorsqu'il est en dehors de cette plage?

Résultat prévu

cp src dst

if time between 9:00-14:00 pause process
After 14:00 resume cp command.
Sollosa
la source
22
rsync peut reprendre des transferts partiels
Thorbjørn Ravn Andersen
2
Avez-vous besoin que les données réelles soient copiées en tant que sauvegarde? Si non, pourriez-vous utiliser cp -alpour créer une ferme hardlink? Ou utilisez un système de fichiers qui prend en charge les liaisons de connexion au niveau des blocs avec la copie sur écriture, en utilisant cp -a --reflink=auto? BTRFS et ZFS prennent cela en charge pour les copies dans le même périphérique physique.
Peter Cordes le
9
Est-ce que certains fichiers srcchangent entre 9h00 et 14h00? Si tel est le cas, une simple pause et une reprise du cpprocessus peuvent endommager les fichiers. Il peut être préférable d’exécuter rsyncen combinaison avec la timeoutcommande.
Mark Plotnick le
De et vers où les fichiers sont-ils copiés? Est-ce un système virtuel? Quel est le système de fichiers source? Quel est le but de la copie?
Braiam
@Braiam Im utilisant rsync et copiant des fichiers d'une machine distante à une machine locale. Je viens d'utiliser la commande cp comme exemple ici
Btw

Réponses:

8

Oui, vous devez

acquire the process id of the process-to-paus (PS), then do
$> kill -SIGSTOP <pid>

Le processus sera alors affiché avec le statut "T" (PS). Pour continuer faire un

$> kill -CONT <pid>

Bonne chance!

gerhard d.
la source
77

Vous pouvez suspendre l'exécution d'un processus en lui envoyant un signal SIGSTOP, puis le reprendre ultérieurement en lui envoyant un SIGCONT.

En supposant que votre charge de travail est un processus unique (vous ne devez pas créer de fichiers d'aide en arrière-plan), vous pouvez utiliser quelque chose comme ceci:

# start copy in background, store pid
cp src dst &
echo "$!" >/var/run/bigcopy.pid

Puis, lorsque le temps occupé commence, envoyez-lui un SIGSTOP:

# pause execution of bigcopy
kill -STOP "$(cat /var/run/bigcopy.pid)"

Plus tard, lorsque le serveur est à nouveau inactif, reprenez-le.

# resume execution of bigcopy
kill -CONT "$(cat /var/run/bigcopy.pid)"

Vous aurez besoin de planifier cela pour des heures spécifiques quand vous voulez qu'il soit exécuté. Vous pouvez utiliser des outils tels que les timers cron ou systemd (ou une variété d'autres outils similaires) pour le planifier. Au lieu de planifier en fonction d'un intervalle de temps, vous pouvez choisir de surveiller le serveur (en examinant éventuellement la charge moyenne, l'utilisation du processeur ou l'activité des journaux du serveur) pour décider du moment opportun pour suspendre / reprendre la copie.

Vous devez également gérer le fichier PID (si vous en utilisez un), assurez-vous que votre copie est toujours en cours d'exécution avant de le suspendre, vous voudrez probablement nettoyer en supprimant le pidfile une fois la copie terminée, etc.

En d’autres termes, vous avez besoin de plus d’informations autour de cela pour rendre le processus fiable, mais l’idée de base consistant à utiliser ces signaux SIGSTOP et SIGCONT pour suspendre / reprendre l’exécution d’un processus semble être ce que vous recherchez.

filbranden
la source
1
Peut-être ajoutez-vous un rappel que vous devez faire très attention que '/var/run/bigcopy.pid' fait toujours référence au même processus que vous le pensez. arrêter de manière aléatoire d'autres processus sur le système peut ne pas être souhaitable. Je ne connais aucun moyen sûr de s’assurer que le pid fait référence au programme que vous pensez bien le faire ...
Evan Benn
@EvanBenn Ouais, c'est ce que je voulais dire par "assurez-vous que votre copie est toujours en cours d'exécution avant de la mettre en pause", même si votre argument est sûrement plus explicite que cela! Ouais, vérifier que les PID sont intrinsèquement
racistes,
@cat Pas vraiment, un processus ne peut pas bloquer SIGSTOP. Voir le lien du premier commentaire: "SIGSTOP est un signal non bloquable comme SIGKILL" (ou tout simplement google, vous verrez que c'est le cas.)
Filbranden
76

Au lieu de suspendre le processus, vous pouvez également lui donner une priorité plus basse:

renice 19 "$pid"

lui donnera la priorité la plus basse (la plus grande gentillesse), de sorte que ce processus cédera le processeur aux autres processus qui en ont le plus souvent besoin.

Sous Linux, on peut faire la même chose avec les E / S avec ionice:

ionice -c idle -p "$pid"

Le processus sera placé dans la classe "inactif", de sorte qu'il obtiendra l'heure du disque uniquement si aucun autre programme n'a demandé d'entrées / sorties disque pour une période de grâce définie .

Stéphane Chazelas
la source
22
C'est un cas typique d'un problème XY . La question était de savoir comment mettre en pause un processus, mais cela ne répond pas à la question. En effet , tout en réduisant la priorité est la meilleure approche du réel problème, il ne répond pas à la question. Je modifier la question d'inclure également comment mettre en pause un processus et pourquoi une pause pourrait être un problème (par exemple , le fichier peut être modifié en mode pause).
MechMK1
22
@ David Stockinger, techniquement, cette réponse explique comment demander au système d'exploitation de suspendre le processus lorsqu'il est occupé (système d'exploitation, processeur, planificateur d'E / S) (même s'il ne s'agit que de fractions de secondes à la fois). La manière de suspendre manuellement le processus a déjà été abordée dans d'autres réponses. Cette solution ne résout pas le problème de la modification des fichiers en cours de copie.
Stéphane Chazelas
5
Changer la priorité d'E / S n'est pas toujours la meilleure solution. Si vous copiez à partir de disques en rotation, vous pouvez toujours effectuer une recherche avant chaque requête de priorité élevée, ce que vous ne feriez pas si vous interrompiez complètement l'opération à priorité basse.
Marc
2
Une priorité inférieure ne résout même pas le problème. Même si la boîte est complètement inactive pendant quelques secondes ou minutes, cela ne signifie pas qu'un processus de copie énorme, qui expulsera tout du cache du système de fichiers, sera discret. Dès qu'il y aura de nouveau une charge, il sera très lent de tout renvoyer en pagination.
R ..
2
@DavidStockinger, le meilleur moyen de traiter les problèmes XY est de donner la bonne solution, même si ce n'est pas ce que la question demande. Lorsque vous savez que l'approche décrite dans la question est fausse, une bonne réponse ne vous donne pas cette mauvaise approche, mais vous propose une meilleure.
terdon
8

Utilisez rsync, oubliez cp, pour ce scénario. il y a des paramètres pour limiter la bande passante, ou peuvent être tués / arrêtés et démarrés plus tard, d'une manière qui va continuer, où il a laissé google rsync example / s

Anton Tománek
la source
3

Si vous voulez le faire en interrompant le processus en cours, je vous suggère de jouer avec le programme Screen. Je n'ai pas utilisé Linux depuis un moment, mais le IIRC met juste en pause la commande et la reprend plus tard, ce qui vous laisse plutôt vulnérable. Si vous vous déconnectez accidentellement, vous ne pourrez pas reprendre votre session.

Avec l’écran, je crois que vous pouvez interrompre la session puis la détacher et vous déconnecter. Plus tard, vous pourrez revenir et vous rattacher à cette session. Il faudrait jouer un peu avec cela, mais cela rendait les sessions beaucoup plus robustes.

Vous pouvez également vous déconnecter et rentrer à la maison, puis vous connecter à distance, vous reconnecter au système que vous avez commencé au bureau et le reprendre pour la soirée, puis le reprendre le lendemain au travail.

Bill K
la source
J'utilise déjà tmux pour cela. Mais je suis en train d’écrire un script qui est conscient de lui-même ou, de préférence, respectueux de l’environnement. Il s’arrête donc si le serveur reçoit un trafic élevé, et continue quand c’est normal.
Sollosa
0

Si votre shell le supporte (presque tous le font), vous pouvez appuyer sur ^ Z (Ctrl + Z) pour envoyer facilement un SIGTSTPsignal à la tâche de premier plan, puis le poursuivre avec fg(au premier plan) ou bg(sur le fond).

Si vous effectuez cette opération sur plusieurs tâches et souhaitez y revenir ultérieurement, vous pouvez utiliser jobscommande, puis renvoyer avec fg/bg %#, où # est le nombre indiqué entre parenthèses pour les travaux.

Gardez à l'esprit que SIGTSTPc'est un peu différent de SIGSTOP(qui est utilisé dans toutes les autres réponses), principalement parce qu'il peut être ignoré (mais je n'ai pas vu un programme l'ignorer autrement que sl). Plus de détails peuvent être trouvés sur cette réponse sur StackOverflow .

Ave
la source
Surpris qu'aucune réponse n'ait encore mentionné cela.
Ave
Ty Ave, je connais ce truc multitâche. Mais pour que cela se produise, il faut être sur un terminal, alors que je devais créer un script qui fera le travail tout seul, peu importe si cela prend des jours.
Sollosa
@Sollosa cela peut être utile à d'autres personnes ayant la même question et ayant accès à un terminal.
Ave
Je suis d'accord.
Bien,