int disconnect_iscsi_target (const char *dev_string) { int pid, retval, status; assert (strlen (home)); logprintfl (EUCAINFO, "disconnect_iscsi_target invoked (dev_string=%s)\n", dev_string); sem_p (iscsi_sem); pid = fork(); if (!pid) { if ( dev_string && strlen(dev_string) ) logprintfl(EUCADEBUG, "disconnect_iscsi_target(): running command: %s %s,%s\n", disconnect_storage_cmd_path, home, dev_string); if (vrun("%s %s,%s", disconnect_storage_cmd_path, home, dev_string) != 0) { logprintfl (EUCAERROR, "ERROR: disconnect_iscsi_target failed\n"); exit(1); } exit(0); } else { retval = timewait(pid, &status, 90); if (retval) { retval = WEXITSTATUS(status); } else { kill(pid, SIGKILL); retval = -1; } } sem_v (iscsi_sem); return retval; }
//! //! Safely terminate a program executed by eucanetd_run_program(). //! //! @param[in] pid the PID of the program to kill //! @param[in] psProgramName a constant string pointer to the program name matching the pid //! @param[in] psRootwrap a constant string pointer to the rootwrap program location //! //! @return 0 on success or 1 on failure //! //! @pre //! - psProgramName should not be NULL //! - The program should be running //! //! @post //! On success, the program is terminated. On failure, we can't tell what happened for sure. //! //! @note //! //! @todo //! We should move this to something more global under util/euca_system.[ch] //! int eucanetd_kill_program(pid_t pid, const char *psProgramName, const char *psRootwrap) { int status = 0; FILE *FH = NULL; char sPid[16] = ""; char sSignal[16] = ""; char cmdstr[EUCA_MAX_PATH] = ""; char file[EUCA_MAX_PATH] = ""; if ((pid < 2) || !psProgramName) { return (EUCA_INVALID_ERROR); } snprintf(file, EUCA_MAX_PATH, "/proc/%d/cmdline", pid); if (check_file(file)) { return (EUCA_PERMISSION_ERROR); } if ((FH = fopen(file, "r")) != NULL) { if (!fgets(cmdstr, EUCA_MAX_PATH, FH)) { fclose(FH); return (EUCA_ACCESS_ERROR); } fclose(FH); } else { return (EUCA_ACCESS_ERROR); } // found running process if (strstr(cmdstr, psProgramName)) { // passed in cmd matches running cmd if (psRootwrap) { snprintf(sPid, 16, "%d", pid); snprintf(sSignal, 16, "-%d", SIGTERM); euca_execlp(NULL, psRootwrap, "kill", sSignal, sPid, NULL); if (timewait(pid, &status, 1) == 0) { LOGERROR("child process {%u} failed to terminate. Attempting SIGKILL.\n", pid); snprintf(sSignal, 16, "-%d", SIGKILL); euca_execlp(NULL, psRootwrap, "kill", sSignal, sPid, NULL); if (timewait(pid, &status, 1) == 0) { LOGERROR("child process {%u} failed to KILL. Attempting SIGKILL again.\n", pid); euca_execlp(NULL, psRootwrap, "kill", sSignal, sPid, NULL); if (timewait(pid, &status, 1) == 0) { return (1); } } } } else { kill(pid, SIGTERM); if (timewait(pid, &status, 1) == 0) { LOGERROR("child process {%u} failed to terminate. Attempting SIGKILL.\n", pid); kill(pid, SIGKILL); if (timewait(pid, &status, 1) == 0) { LOGERROR("child process {%u} failed to KILL. Attempting SIGKILL again.\n", pid); kill(pid, SIGKILL); if (timewait(pid, &status, 1) == 0) { return (1); } } } } } return (0); }
char * get_iscsi_target (const char *dev_string) { char buf [MAX_PATH]; char *retval=NULL; int pid, status, rc, len, rbytes, filedes[2]; assert (strlen (home)); snprintf (buf, MAX_PATH, "%s %s,%s", get_storage_cmd_path, home, dev_string); logprintfl (EUCAINFO, "get_iscsi_target invoked (dev_string=%s)\n", dev_string); rc = pipe(filedes); if (rc) { logprintfl(EUCAERROR, "get_iscsi_target: cannot create pipe\n"); return(NULL); } sem_p (iscsi_sem); pid = fork(); if (!pid) { close(filedes[0]); if (strlen(buf)) logprintfl(EUCADEBUG, "get_iscsi_target(): running command: %s\n", buf); if ((retval = system_output(buf)) == NULL) { logprintfl (EUCAERROR, "ERROR: get_iscsi_target failed\n"); len = 0; } else { logprintfl (EUCAINFO, "Device: %s\n", retval); len = strlen(retval); } rc = write(filedes[1], &len, sizeof(int)); if (retval) { rc = write(filedes[1], retval, sizeof(char) * len); } close(filedes[1]); if (rc == len) { exit(0); } exit(1); } else { close(filedes[1]); rbytes = timeread(filedes[0], &len, sizeof(int), 90); if (rbytes <= 0) { kill(pid, SIGKILL); } else { retval = malloc(sizeof(char) * (len+1)); bzero(retval, len+1); rbytes = timeread(filedes[0], retval, len, 90); if (rbytes <= 0) { kill(pid, SIGKILL); } } close(filedes[0]); rc = timewait(pid, &status, 90); if (rc) { rc = WEXITSTATUS(status); } else { kill(pid, SIGKILL); } } sem_v (iscsi_sem); return retval; }