示例#1
0
/**
 * Restores ebtables state from files.
 *
 * @param ebth [in] pointer to the EB table handler structure
 *
 * @return 0 on success. 1 on failure.
 */
int ebt_system_restore(ebt_handler *ebth) {
    int ret = EUCA_OK;
    if (euca_execlp(NULL, ebth->cmdprefix, "ebtables", "--atomic-file", ebth->ebt_filter_file, "-t", "filter", "--atomic-commit", NULL) != EUCA_OK) {
        copy_file(ebth->ebt_filter_file, "/tmp/euca_ebt_filter_file_failed");
        LOGERROR("ebtables-restore failed. copying failed input file to '/tmp/euca_ebt_filter_file_failed' for manual retry.\n");
        ret = 1;
    }

    if (euca_execlp(NULL, ebth->cmdprefix, "ebtables", "--atomic-file", ebth->ebt_nat_file, "-t", "nat", "--atomic-commit", NULL) != EUCA_OK) {
        copy_file(ebth->ebt_nat_file, "/tmp/euca_ebt_nat_file_failed");
        LOGERROR("ebtables-restore failed. copying failed input file to '/tmp/euca_ebt_nat_file_failed' for manual retry.\n");
        ret = 1;
    }

    unlink_handler_file(ebth->ebt_filter_file);
    unlink_handler_file(ebth->ebt_nat_file);
    unlink_handler_file(ebth->ebt_asc_file);

    return (ret);
}
示例#2
0
/**
 * Saves the current ebtables state to files.
 *
 * @param ebth [in] pointer to the EB table handler structure
 *
 * @return 0 on success. 1 on failure.
 */
int ebt_system_save(ebt_handler *ebth) {
    int ret = 0;

    if (euca_execlp(NULL, ebth->cmdprefix, "ebtables", "--atomic-file", ebth->ebt_filter_file, "-t", "filter", "--atomic-save", NULL) != EUCA_OK) {
        LOGERROR("ebtables-save -t filter failed\n");
        ret = 1;
    }
    if (euca_execlp(NULL, ebth->cmdprefix, "ebtables", "--atomic-file", ebth->ebt_nat_file, "-t", "nat", "--atomic-save", NULL) != EUCA_OK) {
        LOGERROR("ebtables-save -t nat failed\n");
        ret = 1;
    }
    if (euca_execlp_redirect(NULL, NULL, ebth->ebt_asc_file, FALSE, NULL, FALSE, ebth->cmdprefix, "ebtables", "--atomic-file", ebth->ebt_filter_file, "-t", "filter", "-L", NULL) != EUCA_OK) {
        LOGERROR("ebtables-list -t filter failed\n");
        ret = 1;
    }
    if (euca_execlp_redirect(NULL, NULL, ebth->ebt_asc_file, TRUE, NULL, FALSE, ebth->cmdprefix, "ebtables", "--atomic-file", ebth->ebt_nat_file, "-t", "nat", "-L", NULL) != EUCA_OK) {
        LOGERROR("ebtables-list -t filter failed\n");
        ret = 1;
    }
    return (ret);
}
示例#3
0
static int generate_migration_keys(char *host, char *credentials, boolean restart, ncInstance * instance)
{
    int rc = EUCA_OK;
    char euca_rootwrap[EUCA_MAX_PATH] = "";
    char generate_keys[EUCA_MAX_PATH] = "";
    char *euca_base = getenv(EUCALYPTUS_ENV_VAR_NAME);
    char *instanceId = instance ? instance->instanceId : "UNSET";
    static char *most_recent_credentials = NULL;
    static char *most_recent_host = NULL;

    if (!host || !credentials) {
        LOGERROR("[%s] called with invalid arguments for host and/or credentials: host=%s, creds=%s\n", SP(instanceId), SP(host), (credentials == NULL) ? "UNSET" : "present");
        return (EUCA_INVALID_ERROR);
    }

    sem_p(hyp_sem);

    if (most_recent_credentials && most_recent_host && !strcmp(most_recent_credentials, credentials) && !strcmp(most_recent_host, host)) {
        LOGDEBUG("[%s] request to generate key using same information (host='%s', creds=%s) as previous request, skipping\n", instanceId, host,
                 (credentials == NULL) ? "UNSET" : "present");
        sem_v(hyp_sem);
        return (EUCA_OK);
    }

    if (!most_recent_credentials) {
        most_recent_credentials = strdup(credentials);
        LOGDEBUG("[%s] first generation of migration credentials\n", instanceId);
    }

    if (!most_recent_host) {
        most_recent_host = strdup(host);
        LOGDEBUG("[%s] first generation of migration host information: %s\n", instanceId, most_recent_host);
    }
    // So, something has changed.
    if (strcmp(most_recent_credentials, credentials)) {
        EUCA_FREE(most_recent_credentials);
        most_recent_credentials = strdup(credentials);
        LOGDEBUG("[%s] regeneration of migration credentials\n", instanceId);
    }

    if (strcmp(most_recent_host, host)) {
        EUCA_FREE(most_recent_host);
        most_recent_host = strdup(host);
        LOGDEBUG("[%s] regeneration of migration host information: %s\n", instanceId, most_recent_host);
    }
    // TO-DO: Add polling around incoming_migrations_in_progress to prevent restarts during migrations?
    snprintf(generate_keys, EUCA_MAX_PATH, EUCALYPTUS_GENERATE_MIGRATION_KEYS, ((euca_base != NULL) ? euca_base : ""));
    snprintf(euca_rootwrap, EUCA_MAX_PATH, EUCALYPTUS_ROOTWRAP, ((euca_base != NULL) ? euca_base : ""));

    LOGDEBUG("[%s] executing migration key-generator: '%s %s %s %s %s'\n", instanceId, euca_rootwrap, generate_keys, host, credentials, ((restart == TRUE) ? "restart" : ""));
    rc = euca_execlp(NULL, euca_rootwrap, generate_keys, host, credentials, ((restart == TRUE) ? "restart" : ""), NULL);

    sem_v(hyp_sem);

    if (rc) {
        LOGERROR("[%s] cmd '%s %s %s %s %s' failed %d\n", instanceId, euca_rootwrap, generate_keys, host, credentials, ((restart == TRUE) ? "restart" : ""), rc);
        return (EUCA_SYSTEM_ERROR);
    }

    LOGDEBUG("[%s] migration key generation succeeded\n", instanceId);
    return (EUCA_OK);
}
示例#4
0
//!
//! 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);
}
示例#5
0
//!
//! Restart or simply start the local DHCP server so it can pick up the new
//! configuration.
//!
//! @return 0 on success or 1 if a failure occured
//!
//! @see
//!
//! @pre
//!     The DHCP server daemon must be present on the system and the 'config->dhcpDaemon'
//!     path must be properly set.
//!
//! @post
//!     on success, the DHCP server has been restarted. If the configuration file does not
//!     contain any data, the DHCP server is stopped.
//!
//! @note
//!
int eucanetd_kick_dhcpd_server(eucanetdConfig *config)
{
    int ret = 0;
    int rc = 0;
    int pid = 0;
    int status = 0;
    char *psPid = NULL;
    char *psConfig = NULL;
    char sPidFileName[EUCA_MAX_PATH] = "";
    char sConfigFileName[EUCA_MAX_PATH] = "";
    char sLeaseFileName[EUCA_MAX_PATH] = "";
    char sTraceFileName[EUCA_MAX_PATH] = "";
    struct stat mystat = { 0 };

    // Do we have a valid path?
    if (stat(config->dhcpDaemon, &mystat) != 0) {
        LOGERROR("Unable to find DHCP daemon binaries: '%s'\n", config->dhcpDaemon);
        return (1);
    }
    // Setup the path to the various files involved
    snprintf(sPidFileName, EUCA_MAX_PATH, NC_NET_PATH_DEFAULT "/euca-dhcp.pid", config->eucahome);
    snprintf(sLeaseFileName, EUCA_MAX_PATH, NC_NET_PATH_DEFAULT "/euca-dhcp.leases", config->eucahome);
    snprintf(sTraceFileName, EUCA_MAX_PATH, NC_NET_PATH_DEFAULT "/euca-dhcp.trace", config->eucahome);
    snprintf(sConfigFileName, EUCA_MAX_PATH, NC_NET_PATH_DEFAULT "/euca-dhcp.conf", config->eucahome);

    // Retrieve the PID of the current DHCP server process if running
    if (stat(sPidFileName, &mystat) == 0) {
        psPid = file2str(sPidFileName);
        pid = atoi(psPid);
        EUCA_FREE(psPid);

        // If the PID value is valid, kill the server
        if (pid > 1) {
            LOGDEBUG("attempting to kill old dhcp daemon (pid=%d)\n", pid);
            if ((rc = safekillfile(sPidFileName, config->dhcpDaemon, 9, config->cmdprefix)) != 0) {
                LOGWARN("failed to kill previous dhcp daemon\n");
            }
        }
    }
    // Check to make sure the lease file is present
    if (stat(sLeaseFileName, &mystat) != 0) {
        // nope, just create an empty one
        LOGDEBUG("creating stub lease file (%s)\n", sLeaseFileName);
        if ((rc = touch(sLeaseFileName)) != 0) {
            LOGWARN("cannot create empty leasefile\n");
        }
    }
    // We should be able to load the configuration file
    if ((psConfig = file2str(sConfigFileName)) != NULL) {
        // Do we have any "node-" statement
        if (strstr(psConfig, "node-")) {
            // Run the DHCP command
            rc = euca_execlp(&status, config->cmdprefix, config->dhcpDaemon, "-cf", sConfigFileName, "-lf", sLeaseFileName, "-pf", sPidFileName, "-tf", sTraceFileName, NULL);
            if (rc != EUCA_OK) {
                LOGERROR("Fail to restart DHCP server. exitcode='%d'\n", status);
                LOGDEBUG("DHCPD Server Command='%s %s %s %s %s %s %s %s %s %s'\n", config->cmdprefix, config->dhcpDaemon, "-cf", sConfigFileName, "-lf", sLeaseFileName, "-pf",
                         sPidFileName, "-tf", sTraceFileName)
                    ret = 1;
            } else {
                LOGDEBUG("DHCP server restarted successfully\n");
            }
        }
        EUCA_FREE(psConfig);
    }

    return (ret);
}
示例#6
0
//!
//! Main entry point of the application
//!
//! @param[in] argc the number of parameter passed on the command line
//! @param[in] argv the list of arguments
//!
//! @return Always return 0
//!
int main(int argc, char *argv[])
{
    int dom_ids[MAXDOMS] = { 0 };
    int num_doms = 0;
    char *eucahome = NULL;
    char *hypervisor = NULL;
    char rootWrap[EUCA_MAX_PATH] = "";
    char cmd[EUCA_MAX_PATH] = "";
    char hypervisorURL[32] = "";
    virConnectPtr conn = NULL;

    //  logfile (NULL, EUCAFATAL); // suppress all messages

    if (argc != 2) {
        fprintf(stderr, "error: test_nc expects one parameter (name of hypervisor)\n");
        exit(1);
    }

    hypervisor = argv[1];
    if (!strcmp(hypervisor, "kvm") || !strcmp(hypervisor, "qemu")) {
        snprintf(hypervisorURL, 32, "qemu:///system");
    } else if (!strcmp(hypervisor, "xen")) {
        snprintf(hypervisorURL, 32, "xen:///");
    } else if (!strcmp(hypervisor, "not_configured")) {
        fprintf(stderr, "error: HYPERVISOR variable is not set in eucalyptus.conf\n");
        exit(1);
    } else {
        fprintf(stderr, "error: hypervisor type (%s) is not recognized\n", hypervisor);
        exit(1);
    }

    // check that commands that NC needs are there
    if (euca_execlp(NULL, "perl", "--version", NULL) != EUCA_OK) {
        fprintf(stderr, "error: could not run perl\n");
        exit(1);
    }

    if ((eucahome = getenv(EUCALYPTUS_ENV_VAR_NAME)) == NULL) {
        eucahome = strdup("");         // root by default
    } else {
        eucahome = strdup(eucahome);
        // Sanitize this string
        if (euca_sanitize_path(eucahome) != EUCA_OK) {
            EUCA_FREE(eucahome);
            eucahome = strdup("");
        }
    }

    add_euca_to_path(eucahome);

    fprintf(stderr, "looking for system utilities...\n");
    if (diskutil_init(0)) {
        EUCA_FREE(eucahome);
        exit(1);
    }
    // ensure hypervisor information is available
    fprintf(stderr, "ok\n\nchecking the hypervisor...\n");
    snprintf(rootWrap, sizeof(rootWrap), EUCALYPTUS_ROOTWRAP, eucahome);
    if (!strcmp(hypervisor, "kvm") || !strcmp(hypervisor, "qemu")) {
        snprintf(cmd, sizeof(cmd), EUCALYPTUS_HELPER_DIR "/get_sys_info", eucahome);
    } else {
        snprintf(cmd, sizeof(cmd), EUCALYPTUS_HELPER_DIR "/get_xen_info", eucahome);
    }

    if (euca_execlp(NULL, rootWrap, cmd, NULL) != EUCA_OK) {
        fprintf(stderr, "error: could not run '%s %s'\n", rootWrap, cmd);
        EUCA_FREE(eucahome);
        exit(1);
    }
    // check that libvirt can query the hypervisor
    // NULL means local hypervisor
    if ((conn = virConnectOpen(hypervisorURL)) == NULL) {
        print_libvirt_error();
        fprintf(stderr, "error: failed to connect to hypervisor\n");
        EUCA_FREE(eucahome);
        exit(1);
    }

    if ((num_doms = virConnectListDomains(conn, dom_ids, MAXDOMS)) < 0) {
        print_libvirt_error();
        fprintf(stderr, "error: failed to query running domains\n");
        EUCA_FREE(eucahome);
        exit(1);
    }

    fprintf(stdout, "NC test was successful\n");
    EUCA_FREE(eucahome);
    return (0);
}
示例#7
0
/**
 * Dumps ebtables hander state to files and restore this ebtables state into system.
 *
 * @param ebth [in] pointer to the EB table handler structure
 *
 * @return 0 on success. 1 on failure.
 */
int ebt_handler_deploy(ebt_handler *ebth) {
    int i = 0;
    int j = 0;
    int k = 0;
    char cmd[EUCA_MAX_PATH] = "";

    if (!ebth || !ebth->init) {
        return (1);
    }

    // Create tmp files as non-root
    char *strptr = strdup(ebth->cmdprefix);
    ebt_table *tablesbak = ebth->tables;
    int maxtablesbak = ebth->max_tables;
    ebt_handler_init(ebth, strptr);
    ebth->tables = tablesbak;
    ebth->max_tables = maxtablesbak;
    EUCA_FREE(strptr);

    ebt_handler_update_refcounts(ebth);

    if (euca_execlp(NULL, ebth->cmdprefix, "ebtables", "--atomic-file", ebth->ebt_filter_file, "-t", "filter", "--atomic-init", NULL) != EUCA_OK) {
        LOGERROR("ebtables-save failed\n");
        return (1);
    }

    if (euca_execlp(NULL, ebth->cmdprefix, "ebtables", "--atomic-file", ebth->ebt_nat_file, "-t", "nat", "--atomic-init", NULL) != EUCA_OK) {
        LOGERROR("ebtables-save failed\n");
        return (1);
    }

    for (i = 0; i < ebth->max_tables; i++) {
        for (j = 0; j < ebth->tables[i].max_chains; j++) {
            if (strcmp(ebth->tables[i].chains[j].name, "EMPTY") && ebth->tables[i].chains[j].ref_count) {
                if (strcmp(ebth->tables[i].chains[j].name, "INPUT") && strcmp(ebth->tables[i].chains[j].name, "OUTPUT") && strcmp(ebth->tables[i].chains[j].name, "FORWARD")
                    && strcmp(ebth->tables[i].chains[j].name, "PREROUTING") && strcmp(ebth->tables[i].chains[j].name, "POSTROUTING")) {
                    if (!strcmp(ebth->tables[i].name, "filter")) {
                        snprintf(cmd, EUCA_MAX_PATH, "%s ebtables --atomic-file %s -t %s -N %s", ebth->cmdprefix, ebth->ebt_filter_file, ebth->tables[i].name,
                                 ebth->tables[i].chains[j].name);
                        if (euca_exec(cmd) != EUCA_OK) {
                            LOGERROR("command failed: command=%s\n", cmd);
                        }
                    } else if (!strcmp(ebth->tables[i].name, "nat")) {
                        snprintf(cmd, EUCA_MAX_PATH, "%s ebtables --atomic-file %s -t %s -N %s", ebth->cmdprefix, ebth->ebt_nat_file, ebth->tables[i].name,
                                 ebth->tables[i].chains[j].name);
                        if (euca_exec(cmd) != EUCA_OK) {
                            LOGERROR("command failed: command=%s\n", cmd);
                        }
                    }
                }
            }
        }
        for (j = 0; j < ebth->tables[i].max_chains; j++) {
            if (strcmp(ebth->tables[i].chains[j].name, "EMPTY") && ebth->tables[i].chains[j].ref_count) {
                for (k = 0; k < ebth->tables[i].chains[j].max_rules; k++) {
                    if (!strcmp(ebth->tables[i].name, "filter")) {
                        snprintf(cmd, EUCA_MAX_PATH, "%s ebtables --atomic-file %s -t %s -A %s %s", ebth->cmdprefix, ebth->ebt_filter_file, ebth->tables[i].name,
                                 ebth->tables[i].chains[j].name, ebth->tables[i].chains[j].rules[k].ebtrule);
                        if (euca_exec(cmd) != EUCA_OK) {
                            LOGERROR("command failed: command=%s\n", cmd);
                        }
                    } else if (!strcmp(ebth->tables[i].name, "nat")) {
                        snprintf(cmd, EUCA_MAX_PATH, "%s ebtables --atomic-file %s -t %s -A %s %s", ebth->cmdprefix, ebth->ebt_nat_file, ebth->tables[i].name,
                                 ebth->tables[i].chains[j].name, ebth->tables[i].chains[j].rules[k].ebtrule);
                        if (euca_exec(cmd) != EUCA_OK) {
                            LOGERROR("command failed: command=%s\n", cmd);
                        }
                    }
                }
            }
        }
    }
    return (ebt_system_restore(ebth));
}