Example #1
0
void LSCRIU_inc_req_procssed()
{
    if (!LSCRIU_Get_Global_Counter_Type()) {
        ++s_requests_count;
    }

    lscriu_dbg("LSCRIU (%d): s_requests_count %d counter %d\n", getpid(), 
               s_requests_count, s_initial_start_reqs);

    if (s_initial_start_reqs > 0 && s_requests_count <= s_initial_start_reqs) {
        if (LSCRIU_Get_Global_Counter_Type() == CRIU_GCOUNTER_SHM) {
            LSCRIU_Increase_Global_Counter();
            if (s_requests_count >= s_initial_start_reqs) {
                //Maybe this time we can stop to send signal and wait for
                //1 second of select timeout
                //kill( LSCRIU_Get_ppid(), SIGUSR2 );
                lscriu_dbg("LSCRIU (%d): Time to dump main process with semaphore\n",
                           getpid());
            }
        } else {
            kill(LSAPI_Get_ppid(), SIGUSR2);
            lscriu_dbg("LSCRIU (%d): Send kill to main process with signals\n",
                       getpid());
        }
    }
}
Example #2
0
static int init_native_env()
{
    char *pchFd;
    pchFd = getenv("LSAPI_CRIU_SYNC_FD");
    if (!pchFd)
        pchFd = getenv("LSCAPI_CRIU_SYNC_FD");

    const char *image_path;
    image_path = getenv("LSAPI_CRIU_IMAGE_PATH");
    if (!pchFd) {
        lscriu_err("LSCRIU (%d): LSAPI_CRIU_SYNC_FD internal environment "
                   "variable not set - contact Litespeed tech support\n", getpid());
        return -1;
    }
    if (!image_path) {
        lscriu_err("LSCRIU (%d): LSAPI_CRIU_IMAGE_PATH internal environment "
                   "variable not set - contact Litespeed tech support\n", getpid());
        return -1;
    }
    lscriu_dbg("LSCRIU (%d): Checkpoint dump.  ImagePath: %s\n",
               getpid(), image_path);

    s_fd_native = atoi(pchFd);
    lscriu_dbg("LSCRIU (%d): Native checkpoint.  Use filepointer %d (%s) to send "
               "pid %d\n", getpid(), s_fd_native, pchFd, iPidDump);
    s_criu_image_path  = strdup(image_path);
    return 0;
}
Example #3
0
static void LSCRIU_Debugging(void) {
    char *pchCRIUDebug;
    pchCRIUDebug = getenv("LSAPI_CRIU_DEBUG");
    if (!pchCRIUDebug) 
        pchCRIUDebug = getenv("LSCAPI_CRIU_DEBUG");
    //fprintf(stderr,"(%d) LSCRIU: CRIU debug environment variable: %s\n",  
    //        s_pid, pchCRIUDebug);
    // I've made it easy to turn on debugging.  CloudLinux Apache sets
    // LSCAPI_CRIU_DEBUG to nothing to indicate it's on.  Sigh.
    if ((!pchCRIUDebug) ||
        ((!*pchCRIUDebug) ||
         (*pchCRIUDebug == '0') ||
         (*pchCRIUDebug == 'f') ||
         (*pchCRIUDebug == 'F') ||
         (((*pchCRIUDebug == 'O') ||
            (*pchCRIUDebug == 'o')) &&
           ((*(pchCRIUDebug + 1)) &&
            ((*(pchCRIUDebug + 1) == 'F') || (*(pchCRIUDebug + 1) == 'f')))))) 
    {
        lscriu_dbg("LSCRIU (%d): CRIU Debugging disabled by environment\n", s_pid);
        s_criu_debug = 0;
    }
    else {
        s_criu_debug = 1;
        lscriu_dbg("LSCRIU (%d): CRIU Debugging enabled by environment\n", s_pid);
        fprintf(stderr,"LSCRIU (%d): CRIU debug environment variable: %s\n",  
                s_pid, pchCRIUDebug);
    }
}
Example #4
0
static void LSCRIU_try_checkpoint(int *forked_pid)
{
    int iRet;
    pid_t iPid;
    pid_t iPidDump = getpid();

    if (s_tried_checkpoint) {
        lscriu_dbg("LSCRIU (%d): Already tried checkpoint - one time per customer\n",
                   getpid());
        return;
    }
    lscriu_dbg("LSCRIU (%d): Trying checkpoint\n", getpid());
    s_tried_checkpoint = 1;
    if (!s_native) {
        LSCRIU_CloudLinux_Checkpoint();
        return;
    }

    lscriu_dbg("LSCRIU (%d): fork!\n", getpid());
    iPid = fork();
    if (iPid < 0) {
        lscriu_err("LSCRIU (%d): Can't checkpoint due to a fork error: %s\n",
                   getpid(), strerror(errno));
        return;
    }
    if (iPid == 0) {
        int     iResult;
        pid_t   iPidSender;
        pid_t   iPidParent = getppid();

        s_pid = getpid();
        setsid();
        iRet = LSCRIU_Native_Dump(s_pid,
                                  s_criu_image_path,
                                  s_fd_native);
        close(s_fd_native);

        LSCRIU_Wait_Dump_Finsh_Or_Restored(iPidParent);
        LSCRIU_Restored_Error(0, "Restored!");
        LSAPI_reset_server_state();
        s_restored = 1;
    }
    else {
        if (forked_pid)
            *forked_pid = iPid;
    }
    LSCRIU_Set_Initial_Start_Reqs(0);
}
Example #5
0
static void LSCRIU_on_timer(int *forked_pid)
{
    lscriu_dbg("LSCRIU (%d): LSCRIU_on_timer\n", getpid());
    if (LSCRIU_need_checkpoint()) {
        LSCRIU_try_checkpoint(forked_pid);
    }
}
Example #6
0
static void LSCRIU_CloudLinux_Checkpoint(void)
{
    int iRet;
    
    if ((!s_native) && (!s_lscapi_dump_me)) {
        lscriu_dbg("LSCRIU (%d): Not native and unable to dump - abandon one-time "
                   "dump\n", s_pid);
        return;
    }

    iRet = s_lscapi_dump_me();
    if (iRet < 0) {
        char *pchError;
        lscriu_err("LSCRIU: CloudLinux dump of PID: %d, error: %s\n", 
                   s_pid, strerror(errno));
    }
    if (iRet == 0) {
        // Dumped.  To continue the child must send us the handles back
        lscriu_err("LSCRIU: Successful CloudLinux dump of PID: %d\n", s_pid);
    }
    else {
        s_restored = 1;
        LSAPI_reset_server_state();
        /*
         Here we have restored the php process, so we should to tell (via 
         semaphore) mod_lsapi that we are started and ready to receive data.
        */
        LSCRIU_Wink_Server_is_Ready();
        lscriu_err("LSCRIU: Successful CloudLinux restore of PID: %d, parent: %d.\n", 
                   getpid(), getppid());
    }
    LSCRIU_Set_Initial_Start_Reqs(0);
}
Example #7
0
static int LSCRIU_Native_Dump(pid_t iPid,
                              char  *pchImagePath,
                              int   iFdNative) {
    criu_native_dump_t criu_native_dump;
    char *pchLastSlash;

    memset(&criu_native_dump, 0, sizeof(criu_native_dump));
    criu_native_dump.m_iPidToDump = iPid;
    strncpy(criu_native_dump.m_chImageDirectory, pchImagePath,
            sizeof(criu_native_dump.m_chImageDirectory));
    pchLastSlash = strrchr(criu_native_dump.m_chSocketDir,'/');
    if (pchLastSlash) {
        pchLastSlash++;
        (*pchLastSlash) = 0;
    }
    lscriu_dbg("LSCRIU (%d): Sent the dump request to the listener\n", s_pid);
    if (write(iFdNative,
              &criu_native_dump,
              sizeof(criu_native_dump)) == -1) {
        lscriu_err("LSCRIU (%d): Error sending dump request to the listener: %s\n",
                   s_pid, strerror(errno));
        return(-1);
    }
    return 0;
}
Example #8
0
int LSCRIU_Init(void)
{
    s_pid = getpid();
    LSCRIU_Debugging();
    LSCRIU_Init_Env_Parameters();
    if (s_initial_start_reqs && !s_native) {
        if (LSCRIU_load_liblscapi() == -1)
            s_initial_start_reqs = 0;
    }
    if (s_initial_start_reqs) {
        LSCRIU_Wink_Server_is_Ready();
        lscriu_dbg("LSCRIU (%d): LSAPI_Register_Pgrp_Timer_Callback\n", s_pid);
        LSAPI_Register_Pgrp_Timer_Callback(LSCRIU_on_timer);
        LSCRIU_Init_Global_Counter(0);
    }
    return s_initial_start_reqs > 0;
}
Example #9
0
static int LSCRIU_Native_Dump(pid_t iPid,
                              char  *pchImagePath,
                              int   iFdNative) {
    criu_native_dump_t criu_native_dump;
    char *pchLastSlash;
    criu_native_dump_response_t criu_native_dump_response;

    memset(&criu_native_dump, 0, sizeof(criu_native_dump));
    criu_native_dump.m_iPidToDump = iPid;
    strncpy(criu_native_dump.m_chImageDirectory, pchImagePath,
            sizeof(criu_native_dump.m_chImageDirectory));
    pchLastSlash = strrchr(criu_native_dump.m_chSocketDir,'/');
    if (pchLastSlash) {
        pchLastSlash++;
        (*pchLastSlash) = 0;
    }
    lscriu_dbg("LSCRIU (%d): Sent the dump request to the listener\n", s_pid);
    if (write(iFdNative,
              &criu_native_dump,
              sizeof(criu_native_dump)) == -1) {
        lscriu_err("LSCRIU (%d): Error sending dump request to the listener: %s\n", 
                   s_pid, strerror(errno));
        return(-1);
    }
    return 0;
    /* do not wait response.
    //while (sleep(7200));
    if (read(iFdNative,
             &criu_native_dump_response,
             sizeof(criu_native_dump_response)) == -1) {
        // The test will actually fail it!
        //LSCRIU_Restored_Error(1, "Error reading dump socket #%d from parent: %s",
        //                      iFdNative, strerror(errno));
        //return(-1);
    }
    return(-1);
    */
}
Example #10
0
static int LSCRIU_Init_Env_Parameters(void)
{
    const char *p;
    int n;

    p = getenv("LSAPI_INITIAL_START");
    if (!p) 
        p = getenv("LSAPI_BACKEND_INITIAL_START");
    if (p) {
        n = atoi(p);

        if (n > 0) {
            lscriu_dbg("LSCRIU (%d): Set start requests based on environment (%d)\n", 
                       getpid(), n);
            LSCRIU_Set_Initial_Start_Reqs(n);
        } else {
            lscriu_dbg("LSCRIU (%d): LSAPI_INITIAL_START set to 0 disabled\n", 
                       getpid());
            return 0;
        }
    } else {
        lscriu_dbg("LSCRIU (%d): LSAPI_INITIAL_START NOT set - disabled\n", 
                   getpid());
        return 0;
    }
    if (LSAPI_Is_Listen()) {
        lscriu_dbg("LSCRIU (%d): Listening...\n", getpid());
        GlobalCounterType_t gc_type = CRIU_GCOUNTER_SHM;
        char *env;
        if ((env = getenv("LSAPI_CRIU_USE_SHM"))) {
            // CloudLinux doc: Off (shared memory) or Signals.  
            // Litespeed doc: On (shared memory) or Signals
            // So just check the first character for an 'S' and if not, then 
            // use shared memory.  Pipe support is lost (sigh).
            if ((*env == 'S') || (*env == 's')) 
                gc_type = CRIU_GCOUNTER_SIG; // Just assume the rest is signals
            // else use the default of shared memory
        }
        else if ((env = getenv("LSAPI_SIGNALS"))) {
            if ((*env == '1') ||
                (*env == 'Y') ||
                (*env == 'y') ||
                (*env == 'T') ||
                (*env == 't') ||
                (((*env == 'O') || (*env == 'o')) &&
                 ((*(env + 1) == 'N') || (*(env + 1) == 'n'))))
                gc_type = CRIU_GCOUNTER_SIG;
            else if (*env == 2) 
                gc_type = CRIU_GCOUNTER_PIPE; // The only case for pipe
            //else use the default of shared memory
        }
        if (gc_type != CRIU_GCOUNTER_SHM) {
            lscriu_dbg("LSCRIU (%d): Use %s\n", getpid(),
                       gc_type == CRIU_GCOUNTER_SIG ? "signals" : "pipe");
            lsapi_criu_signal(SIGUSR2, lsapi_siguser2);
        }
        else
            lscriu_dbg("LSCRIU (%d): Use shared memory\n", getpid());
        LSCRIU_Set_Global_Counter_Type(gc_type);
    }
    else 
        lscriu_dbg("LSCRIU (%d): NOT Listening\n", getpid());

    char *criu_mode = NULL;
    char ch;
    criu_mode = getenv("LSAPI_CRIU");
    // 0 disabled
    // 1 cloudlinux
    // 2 native
    if (criu_mode) {
        if (*criu_mode == '0') {
             lscriu_dbg("LSCRIU (%d): Disabled by environment.\n", getpid());
             LSCRIU_Set_Initial_Start_Reqs(0);
        }
        else if (*criu_mode == '2') {
            lscriu_dbg("LSCRIU (%d): Disabled by environment.\n", getpid());
            s_native = 1;
        }
    }

    if (s_native && init_native_env() == -1)
        LSCRIU_Set_Initial_Start_Reqs(0);

    //unset_lsapi_envs();
    return 0;
}