コード例 #1
0
ファイル: ionice_fork.c プロジェクト: ilovezfs/ionice
int
run_process(const char *path, char *argv[], int flags)
{
        pid_t pid;
        int rc, devnull_fd;
        char **argp;

        pid = vfork();
        if (pid == 0) {
                devnull_fd = open("/dev/null", O_WRONLY);

                if (devnull_fd < 0)
                        _exit(-1);

                if (!(flags & STDOUT_VERBOSE))
                        (void) dup2(devnull_fd, STDOUT_FILENO);

                if (!(flags & STDERR_VERBOSE))
                        (void) dup2(devnull_fd, STDERR_FILENO);

                close(devnull_fd);
#if 0
        { int i;
        fprintf(stderr, "Running process: ");
        for (i = 0; argv[i]; i++)
            fprintf(stderr, "'%s' ", argv[i]);
        fprintf(stderr, "\r\n");
        }
#endif
                setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_THROTTLE);
                (void) execvp(path, argv);
		perror(path);
                _exit(-1);
        } else if (pid > 0) {
                int status;

                while ((rc = waitpid(pid, &status, 0)) == -1 &&
                        errno == EINTR);
                if (rc < 0 || !WIFEXITED(status))
                        return (-1);

                return (WEXITSTATUS(status));
        }

        return (-1);
}
コード例 #2
0
ファイル: init.cpp プロジェクト: 200GAUTAM/osquery
void Initializer::initDaemon() const {
  if (FLAGS_config_check) {
    // No need to daemonize, emit log lines, or create process mutexes.
    return;
  }

#ifndef __APPLE__
  // OS X uses launchd to daemonize.
  if (osquery::FLAGS_daemonize) {
    if (daemon(0, 0) == -1) {
      shutdown(EXIT_FAILURE);
    }
  }
#endif

  // Print the version to SYSLOG.
  syslog(
      LOG_NOTICE, "%s started [version=%s]", binary_.c_str(), kVersion.c_str());

  // Check if /var/osquery exists
  if ((Flag::isDefault("pidfile") || Flag::isDefault("database_path")) &&
      !isDirectory(OSQUERY_HOME)) {
    std::cerr << CONFIG_ERROR;
  }

  // Create a process mutex around the daemon.
  auto pid_status = createPidFile();
  if (!pid_status.ok()) {
    LOG(ERROR) << binary_ << " initialize failed: " << pid_status.toString();
    shutdown(EXIT_FAILURE);
  }

  // Nice ourselves if using a watchdog and the level is not too permissive.
  if (!FLAGS_disable_watchdog &&
      FLAGS_watchdog_level >= WATCHDOG_LEVEL_DEFAULT &&
      FLAGS_watchdog_level != WATCHDOG_LEVEL_DEBUG) {
    // Set CPU scheduling I/O limits.
    setpriority(PRIO_PGRP, 0, 10);
#ifdef __linux__
    // Using: ioprio_set(IOPRIO_WHO_PGRP, 0, IOPRIO_CLASS_IDLE);
    syscall(SYS_ioprio_set, IOPRIO_WHO_PGRP, 0, IOPRIO_CLASS_IDLE);
#elif defined(__APPLE__)
    setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_THROTTLE);
#endif
  }
}
コード例 #3
0
ファイル: init.cpp プロジェクト: justintime32/osquery
void Initializer::initDaemon() const {
  if (FLAGS_config_check) {
    // No need to daemonize, emit log lines, or create process mutexes.
    return;
  }

#if !defined(__APPLE__) && !defined(WIN32)
  // OS X uses launchd to daemonize.
  if (osquery::FLAGS_daemonize) {
    if (daemon(0, 0) == -1) {
      shutdown(EXIT_FAILURE);
    }
  }
#endif

  // Print the version to the OS system log.
  systemLog(binary_ + " started [version=" + kVersion + "]");

  if (!FLAGS_ephemeral) {
    if ((Flag::isDefault("pidfile") || Flag::isDefault("database_path")) &&
        !isDirectory(OSQUERY_HOME)) {
      std::cerr << CONFIG_ERROR;
    }

    // Create a process mutex around the daemon.
    auto pid_status = createPidFile();
    if (!pid_status.ok()) {
      LOG(ERROR) << binary_ << " initialize failed: " << pid_status.toString();
      shutdown(EXIT_FAILURE);
    }
  }

  // Nice ourselves if using a watchdog and the level is not too permissive.
  if (!FLAGS_disable_watchdog && FLAGS_watchdog_level >= 0) {
    // Set CPU scheduling I/O limits.
    setToBackgroundPriority();

#ifdef __linux__
    // Using: ioprio_set(IOPRIO_WHO_PGRP, 0, IOPRIO_CLASS_IDLE);
    syscall(SYS_ioprio_set, IOPRIO_WHO_PGRP, 0, IOPRIO_CLASS_IDLE);
#elif defined(__APPLE__)
    setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_THROTTLE);
#endif
  }
}
コード例 #4
0
ファイル: ionice_fork.c プロジェクト: ilovezfs/ionice
int main(int argc, char *argv[])
{
        int c;

        if (argc < 2)
        {
                fprintf(stderr, "Usage: %s <command>\n", argv[0]);
                exit(EXIT_FAILURE);
        }

        while ((c = getopt(argc, argv, "c:")) != -1);

        argc -= optind;
        argv += optind;

        setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_THROTTLE);
        int err = run_process(argv[0], &argv[0], 0x03);
        exit (err);
}
コード例 #5
0
int main(int argc, char * argv[])
{
	int ch, ret;
	bool flagx = false, flagX = false, flagb = false;
	int flagd = -1, flagg = -1;
	struct task_qos_policy qosinfo = { LATENCY_QOS_TIER_UNSPECIFIED, THROUGHPUT_QOS_TIER_UNSPECIFIED };
	
	while ((ch = getopt(argc, argv, "xXbd:g:t:l:")) != -1) {
		switch (ch) {
			case 'x':
				flagx = true;
				break;
			case 'X':
				flagX = true;
				break;
			case 'b':
				flagb = true;
				break;
			case 'd':
				flagd = parse_disk_policy(optarg);
				if (flagd == -1) {
					warnx("Could not parse '%s' as a disk policy", optarg);
					usage();
				}
				break;
			case 'g':
				flagg = parse_disk_policy(optarg);
				if (flagg == -1) {
					warnx("Could not parse '%s' as a disk policy", optarg);
					usage();
				}
				break;
			case 't':
				qosinfo.task_throughput_qos_tier = parse_qos_tier(optarg, QOS_PARAMETER_THROUGHPUT);
				if (qosinfo.task_throughput_qos_tier == -1) {
					warnx("Could not parse '%s' as a qos tier", optarg);
					usage();
				}
				break;
			case 'l':
				qosinfo.task_latency_qos_tier = parse_qos_tier(optarg, QOS_PARAMETER_LATENCY);
				if (qosinfo.task_latency_qos_tier == -1) {
					warnx("Could not parse '%s' as a qos tier", optarg);
					usage();
				}
				break;
			case '?':
			default:
				usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (argc == 0) {
		usage();
	}
	
	if (flagx && flagX){
		warnx("Incompatible options -x, -X");
		usage();
	}

	if (flagx) {
		ret = setiopolicy_np(IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY, IOPOL_SCOPE_PROCESS, IOPOL_VFS_HFS_CASE_SENSITIVITY_FORCE_CASE_SENSITIVE);
		if (ret == -1) {
			err(EX_SOFTWARE, "setiopolicy_np(IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY...)");
		}
	}

	if (flagX) {
		ret = setiopolicy_np(IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY, IOPOL_SCOPE_PROCESS, IOPOL_VFS_HFS_CASE_SENSITIVITY_DEFAULT);
		if (ret == -1) {
			err(EX_SOFTWARE, "setiopolicy_np(IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY...)");
		}
	}

	if (flagb) {
		ret = setpriority(PRIO_DARWIN_PROCESS, 0, PRIO_DARWIN_BG);
		if (ret == -1) {
			err(EX_SOFTWARE, "setpriority()");
		}
	}

	if (flagd >= 0) {
		ret = setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, flagd);
		if (ret == -1) {
			err(EX_SOFTWARE, "setiopolicy_np(...IOPOL_SCOPE_PROCESS...)");
		}
	}

	if (flagg >= 0){
		ret = setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_DARWIN_BG, flagg);
		if (ret == -1) {
			err(EX_SOFTWARE, "setiopolicy_np(...IOPOL_SCOPE_DARWIN_BG...)");
		}
	}

	if (qosinfo.task_latency_qos_tier != LATENCY_QOS_TIER_UNSPECIFIED ||
	    qosinfo.task_throughput_qos_tier != THROUGHPUT_QOS_TIER_UNSPECIFIED){
		ret = task_policy_set(mach_task_self(), TASK_OVERRIDE_QOS_POLICY, (task_policy_t)&qosinfo, TASK_QOS_POLICY_COUNT);
		if (ret != KERN_SUCCESS){
			err(EX_SOFTWARE, "task_policy_set(...TASK_OVERRIDE_QOS_POLICY...)");
		}
	}
	
	ret = execvp(argv[0], argv);
	if (ret == -1) {
		err(EX_NOINPUT, "Could not execute %s", argv[0]);
	}
	
	return EX_OSERR;
}
コード例 #6
0
int main(int argc, char * argv[])
{
    int ch, ret;
    pid_t pid = 0;
    posix_spawnattr_t attr;
    extern char **environ;
    bool flagx = false, flagX = false, flagb = false, flagB = false;
    int flagd = -1, flagg = -1;
    struct task_qos_policy qosinfo = { LATENCY_QOS_TIER_UNSPECIFIED, THROUGHPUT_QOS_TIER_UNSPECIFIED };
    uint64_t qos_clamp = POSIX_SPAWN_PROC_CLAMP_NONE;

    while ((ch = getopt(argc, argv, "xXbBd:g:c:t:l:p:")) != -1) {
        switch (ch) {
        case 'x':
            flagx = true;
            break;
        case 'X':
            flagX = true;
            break;
        case 'b':
            flagb = true;
            break;
        case 'B':
            flagB = true;
            break;
        case 'd':
            flagd = parse_disk_policy(optarg);
            if (flagd == -1) {
                warnx("Could not parse '%s' as a disk policy", optarg);
                usage();
            }
            break;
        case 'g':
            flagg = parse_disk_policy(optarg);
            if (flagg == -1) {
                warnx("Could not parse '%s' as a disk policy", optarg);
                usage();
            }
            break;
        case 'c':
            qos_clamp = parse_qos_clamp(optarg);
            if (qos_clamp == POSIX_SPAWN_PROC_CLAMP_NONE) {
                warnx("Could not parse '%s' as a QoS clamp", optarg);
                usage();
            }
            break;
        case 't':
            qosinfo.task_throughput_qos_tier = parse_qos_tier(optarg, QOS_PARAMETER_THROUGHPUT);
            if (qosinfo.task_throughput_qos_tier == -1) {
                warnx("Could not parse '%s' as a qos tier", optarg);
                usage();
            }
            break;
        case 'l':
            qosinfo.task_latency_qos_tier = parse_qos_tier(optarg, QOS_PARAMETER_LATENCY);
            if (qosinfo.task_latency_qos_tier == -1) {
                warnx("Could not parse '%s' as a qos tier", optarg);
                usage();
            }
            break;
        case 'p':
            pid = atoi(optarg);
            if (pid == 0) {
                warnx("Invalid pid '%s' specified", optarg);
                usage();
            }
            break;
        case '?':
        default:
            usage();
        }
    }
    argc -= optind;
    argv += optind;

    if (pid == 0 && argc == 0) {
        usage();
    }

    if (pid != 0 && (flagx || flagX || flagg != -1 || flagd != -1)) {
        warnx("Incompatible option(s) used with -p");
        usage();
    }

    if (flagx && flagX) {
        warnx("Incompatible options -x, -X");
        usage();
    }

    if (flagb && flagB) {
        warnx("Incompatible options -b, -B");
        usage();
    }

    if (flagB && pid == 0) {
        warnx("The -B option can only be used with the -p option");
        usage();
    }

    if (flagx) {
        ret = setiopolicy_np(IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY, IOPOL_SCOPE_PROCESS, IOPOL_VFS_HFS_CASE_SENSITIVITY_FORCE_CASE_SENSITIVE);
        if (ret == -1) {
            err(EX_SOFTWARE, "setiopolicy_np(IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY...)");
        }
    }

    if (flagX) {
        ret = setiopolicy_np(IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY, IOPOL_SCOPE_PROCESS, IOPOL_VFS_HFS_CASE_SENSITIVITY_DEFAULT);
        if (ret == -1) {
            err(EX_SOFTWARE, "setiopolicy_np(IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY...)");
        }
    }

    if (flagb) {
        ret = setpriority(PRIO_DARWIN_PROCESS, pid, PRIO_DARWIN_BG);
        if (ret == -1) {
            err(EX_SOFTWARE, "setpriority()");
        }
    }

    if (flagB) {
        ret = setpriority(PRIO_DARWIN_PROCESS, pid, 0);
        if (ret == -1) {
            err(EX_SOFTWARE, "setpriority()");
        }
    }

    if (flagd >= 0) {
        ret = setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, flagd);
        if (ret == -1) {
            err(EX_SOFTWARE, "setiopolicy_np(...IOPOL_SCOPE_PROCESS...)");
        }
    }

    if (flagg >= 0) {
        ret = setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_DARWIN_BG, flagg);
        if (ret == -1) {
            err(EX_SOFTWARE, "setiopolicy_np(...IOPOL_SCOPE_DARWIN_BG...)");
        }
    }

    if (qosinfo.task_latency_qos_tier != LATENCY_QOS_TIER_UNSPECIFIED ||
            qosinfo.task_throughput_qos_tier != THROUGHPUT_QOS_TIER_UNSPECIFIED) {
        mach_port_t task;
        if (pid) {
            ret = task_for_pid(mach_task_self(), pid, &task);
            if (ret != KERN_SUCCESS) {
                err(EX_SOFTWARE, "task_for_pid(%d) failed", pid);
                return EX_OSERR;
            }
        } else {
            task = mach_task_self();
        }
        ret = task_policy_set((task_t)task, TASK_OVERRIDE_QOS_POLICY, (task_policy_t)&qosinfo, TASK_QOS_POLICY_COUNT);
        if (ret != KERN_SUCCESS) {
            err(EX_SOFTWARE, "task_policy_set(...TASK_OVERRIDE_QOS_POLICY...)");
        }
    }

    if (pid != 0)
        return 0;


    ret = posix_spawnattr_init(&attr);
    if (ret != 0) errc(EX_NOINPUT, ret, "posix_spawnattr_init");

    ret = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETEXEC);
    if (ret != 0) errc(EX_NOINPUT, ret, "posix_spawnattr_setflags");

    if (qos_clamp != POSIX_SPAWN_PROC_CLAMP_NONE) {
        ret = posix_spawnattr_set_qos_clamp_np(&attr, qos_clamp);
        if (ret != 0) errc(EX_NOINPUT, ret, "posix_spawnattr_set_qos_clamp_np");
    }

    ret = posix_spawnp(&pid, argv[0], NULL, &attr, argv, environ);
    if (ret != 0) errc(EX_NOINPUT, ret, "posix_spawn");

    return EX_OSERR;
}
コード例 #7
0
ファイル: fork_program.c プロジェクト: Annovae/kext_tools
/*******************************************************************************
* Fork a process after a specified delay, and either wait on it to exit or
* leave it to run in the background.
*
* Returns -2 on spawn() failure, -1 on other failure, and depending on wait:
* wait: true - exit status of forked program
* wait: false - pid of background process
*******************************************************************************/
int fork_program(const char * argv0, char * const argv[], Boolean wait)
{
    int            result;
    int            spawn_result;
    pid_t          child_pid;
    int            child_status;
    int            normal_iopolicy = getiopolicy_np(IOPOL_TYPE_DISK,
                                                    IOPOL_SCOPE_PROCESS);
    char ** environ = *(_NSGetEnviron());

    if (!wait) {
        setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_THROTTLE);
    }

    spawn_result = posix_spawn(&child_pid, argv0, /* file_actions */ NULL,
        /* spawnattrs */ NULL, argv, environ);

    // If we couldn't spawn the process, return -2 with errno for detail
    if (spawn_result != 0) {
        OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel,
            "posix_spawn failed for %s.", argv0);
        errno = spawn_result;
        result = -2;
        goto finish;
    }

    OSKextLog(/* kext */ NULL, kOSKextLogDetailLevel,
              "started child process %s[%d] (%ssynchronous).",
              argv0, child_pid, wait ? "" : "a");

    if (wait) {
        OSKextLogSpec logSpec = kOSKextLogDetailLevel;
        if (waitpid(child_pid, &child_status, 0) == -1) {
            result = -1;
            goto finish;
        }
        if (WIFEXITED(child_status)) {
            result = WEXITSTATUS(child_status);
            if (result) {
                logSpec = kOSKextLogErrorLevel;
            }
            OSKextLog(/* kext */ NULL, logSpec,
                "Child process %s[%d] exited with status %d.",
                argv0, child_pid, result);
        } else if (WIFSIGNALED(child_status)) {
            result = WTERMSIG(child_status);
            logSpec = kOSKextLogErrorLevel;
            OSKextLog(/* kext */ NULL, logSpec,
                "Child process %s[%d] exited due to signal %d.",
                argv0, child_pid, result);
        } else {
            // shouldn't be any other types of exit
            result = -1;
        }
    } else {
        result = child_pid;
    }

finish:
    setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, normal_iopolicy);
    
    return result;
}