How to run VM hooks asynchronously

Discussion in 'Proxmox VE: Installation and configuration' started by danielb, Jun 14, 2019 at 18:22.

Tags:
  1. danielb

    danielb Member

    Joined:
    Jun 1, 2018
    Messages:
    73
    Likes Received:
    14
    For my need (see https://forum.proxmox.com/threads/running-hooks-when-incoming-migration-is-finished.54330 for some background), I need to run a hook script when a VM ends an incoming live migration. I'm trying to use the post-start hook. The idea : in the post-start hook, loop to see if the VM is running on the local node. If not, the migration is still running, if yes, it has finished the live migration and I can proceed with my custom script.

    The problem is that hooks are blocking. Even post-start. As long as post-start has not returned, the migration won't proceed, as PVE consideres the VM is still starting. I tried to fork in my hook script, or to use a shell wrapper, calling the real one with &. But in both case it's the same. PVE dosn't start migration and juste blocks in the post-start hook. Not sure why, are hooks executed in a special cgroup which ensure even forks are ended ?

    How can I fire a hook asynchronously ? I'd prefer not having to write a separate daemon which could receive signals from the hook script and do the async part
     
  2. wolfgang

    wolfgang Proxmox Staff Member
    Staff Member

    Joined:
    Oct 1, 2014
    Messages:
    4,697
    Likes Received:
    310
    Hi,
    You can do this with a fork of a new process.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  3. danielb

    danielb Member

    Joined:
    Jun 1, 2018
    Messages:
    73
    Likes Received:
    14
    This is where I'm lost. My hook is a perl script, and running in a simple fork() still blocks the hookThis is where it's getting strange. In my hook, I have something like this :


    Code:
    $SIG{CHLD} = 'IGNORE';
    
    if ($phase eq 'post-start') {
      my $pid = fork();
      if ($pid) {
        print "Will run pre-start routine in the background\n";
      } elsif ( defined $pid ) {
        # Long running part which should be in the background
      }
    }
    
    Running this from the CLI, the script correctly detach itself. But when called but Proxmox as a hook, it's still blocking (in my case, it blocks the "Starting VM" part, and so the migration does not start. I'm probably doing it wrong, but I don't understand why it works from the CLI and not as a hook
     
  4. wolfgang

    wolfgang Proxmox Staff Member
    Staff Member

    Joined:
    Oct 1, 2014
    Messages:
    4,697
    Likes Received:
    310
    Code:
    #!/usr/bin/perl
    use strict;
    use warnings;
    my $pid = fork();
    if ($pid != 0) {
        exit;
    } else {
        print "$$\n";
        sleep(1000);
        print "Done\n";
    }
    
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  5. danielb

    danielb Member

    Joined:
    Jun 1, 2018
    Messages:
    73
    Likes Received:
    14
    This exact code will block the hook (just tried)
     
  6. wolfgang

    wolfgang Proxmox Staff Member
    Staff Member

    Joined:
    Oct 1, 2014
    Messages:
    4,697
    Likes Received:
    310
    Code:
    my $pid = fork();
    if ($pid != 0) {
        POSIX::_exit 0;
    } else {
    close STDOUT;
    close STDERR;
    close STDIN;
    POSIX::setsid();
    #Do your things like 
    sleep(100);
    }
    
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  7. danielb

    danielb Member

    Joined:
    Jun 1, 2018
    Messages:
    73
    Likes Received:
    14
    Yeah ! I found that I needed to close STDOUT and STDERR, but was missing the setsid part. Many thanks !!
     
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice