예제 #1
0
파일: cache.c 프로젝트: sosilent/euca
// remove file and its summary in work directory
void rm_workfile (const char * filename)
{
    char file_path [EUCA_MAX_PATH];
    char summ_path [EUCA_MAX_PATH];

    snprintf (file_path, EUCA_MAX_PATH, "%s/%s", get_work_dir(), filename);
    snprintf (summ_path, EUCA_MAX_PATH, "%s/%s-summary", get_work_dir(), filename);

    unlink (file_path); // ignore errors
    unlink (summ_path);
}
예제 #2
0
gboolean daemon_init(hsb_daemon_config *my_daemon, gboolean background)
{
	int fd ;
	const char *work_dir = get_work_dir();

	if ( background == TRUE )
		if ( -1 == daemon(0,0) )
			return FALSE;

	umask(0022);
	mkdir(work_dir, 0755);

	if ( -1 == chdir(work_dir) )
		return FALSE ;

	if (total_cfg_read() == FALSE)
		return FALSE;

	if (create_pid_file(my_daemon->pid_file)) 
		return FALSE;

	fd = unix_socket_new_listen( my_daemon->unix_listen_path ) ;
	if (-1 == fd)
	{
		unlink(my_daemon->pid_file);
		unlink(my_daemon->unix_listen_path);
		return FALSE;
	} 

	my_daemon->unix_listen_fd = fd;

	return TRUE;
}
예제 #3
0
파일: cache.c 프로젝트: sosilent/euca
// finds disc item on disk (in work or cache), allocates and fills out memory struct for it
disk_item * find_disk_item (const char * id, const boolean cache_item)
{
    char path [EUCA_MAX_PATH];

    if (cache_item) {
        snprintf (path, EUCA_MAX_PATH, "%s/%s/content", get_cache_dir(), id);
    } else {
        snprintf (path, EUCA_MAX_PATH, "%s/%s", get_work_dir(), id);
    }

    if (cache_item) {
        scan_cache (); // rebuilds cache state in memory based on disk
        return find_in_cache (path);
    }

    struct stat mystat;
    if (stat (path, &mystat)<0) {
        if (errno!=ENOENT) { // file not found
            logprintfl (EUCAERROR, "error: could not stat '%s'\n", path);
        }
        return NULL;
    }

    return alloc_disk_item (id, mystat.st_size, mystat.st_size, cache_item);
}
예제 #4
0
 const char* ExpireService::get_pid_file_path()
 {
   const char* pid_file_path = NULL;
   const char* work_dir = get_work_dir();
   if (work_dir != NULL)
   {
     pid_file_path_ = work_dir;
     pid_file_path_ += "/logs/expireserver";
     pid_file_path_ += ".pid";
     pid_file_path = pid_file_path_.c_str();
   }
   return pid_file_path;
 }
예제 #5
0
 const char* ExpireService::get_log_file_path()
 {
   const char* log_file_path = NULL;
   const char* work_dir = get_work_dir();
   if (work_dir != NULL)
   {
     log_file_path_ = work_dir;
     log_file_path_ += "/logs/expireserver";
     log_file_path_ +=  ".log";
     log_file_path = log_file_path_.c_str();
   }
   return log_file_path;
 }
예제 #6
0
파일: cache.c 프로젝트: sosilent/euca
int clean_work_dir (blobstore * work_bs)
{
    char path [EUCA_MAX_PATH];
    sprintf (path, "%s/imager.pid", get_work_dir());
    unlink (path);
    
    if (work_bs)
        blobstore_delete (work_bs); // not fully implemented, but will delete artifacts of an empty blobstore
    
    if (work_was_created)
        return rmdir (work_path);
    
    return 0;
}
예제 #7
0
파일: cache.c 프로젝트: sosilent/euca
// allocates disc item struct in memory, but does nothing on disk
disk_item * alloc_disk_item (const char * id, const long long content_size, const long long total_size, boolean cache_item)
{
    disk_item * di = calloc (1, sizeof(disk_item));
    if (di==NULL) {
        logprintfl (EUCAERROR, "error: out of memory in alloc_disk_item()\n");
        return di;
    }
    safe_strncpy (di->id, id, EUCA_MAX_PATH);
    if (cache_item) {
        snprintf (di->base, EUCA_MAX_PATH, "%s/%s",      get_cache_dir(), di->id);
        snprintf (di->path, EUCA_MAX_PATH, "%s/content", di->base);
        snprintf (di->summ, EUCA_MAX_PATH, "%s/summary", di->base);
    } else {
        snprintf (di->base, EUCA_MAX_PATH, "%s",            get_work_dir());
        snprintf (di->path, EUCA_MAX_PATH, "%s/%s",         di->base, di->id);
        snprintf (di->summ, EUCA_MAX_PATH, "%s/%s-summary", di->base, di->id);
    }
    di->cache_item = cache_item;
    di->total_size = total_size;
    di->content_size = content_size;

    return di;
}
예제 #8
0
파일: cache.c 프로젝트: sosilent/euca
char * alloc_tmp_file (const char * name_base, long long size)
{
    if (reserve_work_path(size)) {
        logprintfl (EUCAERROR, "out of work disk space for a temporary file\n");
        return NULL;
    }
    char * path = malloc (EUCA_MAX_PATH);
    if (path==NULL) {
        logprintfl (EUCAERROR, "out of memory in alloc_tmp_file()\n");
        return NULL;
    }

    snprintf (path, EUCA_MAX_PATH, "%s/%s-XXXXXX", get_work_dir(), name_base);
    int tmp_fd = safe_mkstemp (path);
    if (tmp_fd<0) {
        logprintfl (EUCAERROR, "error: failed to create a temporary file under %s\n", path);
        free(path);
        return NULL;
    }
    close (tmp_fd);

    return path;
}
예제 #9
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 EUCA_OK on success or EUCA_ERROR on failure.
//!
int main(int argc, char *argv[])
{
    int i = 0;
    int ret = EUCA_OK;
    int nparams = 0;
    int ncmds = 0;
    char *eq = NULL;
    char *key = NULL;
    char *val = NULL;
    char euca_root[] = "";
    char argv_str[4096] = "";
    char *cmd_name = NULL;
    char pid_file[EUCA_MAX_PATH] = "";
    FILE *fp = NULL;
    pid_t pid = 0;
    artifact *root = NULL;
    blobstore *work_bs = NULL;
    blobstore *cache_bs = NULL;
    imager_param *cmd_params = NULL;

    log_fp_set(stderr); // imager logs to stderr so image data can be piped to stdout
    set_debug(print_debug);

    // initialize globals
    artifacts_map = map_create(10);

    // use $EUCALYPTUS env var if available
    euca_home = getenv(EUCALYPTUS_ENV_VAR_NAME);
    if (!euca_home) {
        euca_home = euca_root;
    }
    // save the command line into a buffer so it's easier to rerun it by hand
    argv_str[0] = '\0';
    for (i = 0; i < argc; i++) {
        strncat(argv_str, "\"", sizeof(argv_str) - strlen(argv_str) - 1);
        strncat(argv_str, argv[i], sizeof(argv_str) - strlen(argv_str) - 1);
        strncat(argv_str, "\" ", sizeof(argv_str) - strlen(argv_str) - 1);
    }

    // initialize dependencies
    if (vmdk_init() == EUCA_OK) {
        vddk_available = TRUE;
    }

    // parse command-line parameters
    while (*(++argv)) {
        eq = strstr(*argv, "=");       // all params have '='s
        if (eq == NULL) {              // it's a command
            // process previous command, if any
            if (validate_cmd(ncmds, cmd_name, cmd_params, *argv) != NULL)
                ncmds++;               // increment only if there was a previous command

            if (ncmds + 1 > MAX_REQS)
                err("too many commands (max is %d)", MAX_REQS);

            cmd_name = *argv;
            cmd_params = NULL;
            nparams = 0;
        } else {                       // this is a parameter
            if (strlen(eq) == 1)
                usage("parameters must have non-empty values");
            *eq = '\0';                // split key from value
            if (strlen(*argv) == 1)
                usage("parameters must have non-empty names");

            key = *argv;
            val = eq + 1;
            if (key == NULL || val == NULL)
                usage("syntax error in parameters");

            if (key[0] == '-')
                key++;                 // skip '-' if any

            if (key[0] == '-')
                key++;                 // skip second '-' if any

            if (cmd_name == NULL) {    // without a preceding command => global parameter
                set_global_parameter(key, val);
                continue;
            }

            if (cmd_params == NULL) {
                cmd_params = calloc(MAX_PARAMS + 1, sizeof(imager_param));  // +1 for terminating NULL
                if (!cmd_params)
                    err("calloc failed");
            }

            if (nparams + 1 > MAX_PARAMS)
                err("too many parameters (max is %d)", MAX_PARAMS);
            cmd_params[nparams].key = key;
            cmd_params[nparams].val = val;
            nparams++;
        }
    }

    if (validate_cmd(ncmds, cmd_name, cmd_params, *argv) != NULL)   // validate last command
        ncmds++;

    LOGINFO("verified all parameters for %d command(s)\n", ncmds);
    if (print_argv) {
        LOGDEBUG("argv[]: %s\n", argv_str);
    }
    // record PID, which may be used by VB to kill the imager process (e.g., in cancelBundling)
    pid = getpid();
    sprintf(pid_file, "%s/imager.pid", get_work_dir());
    if ((fp = fopen(pid_file, "w")) == NULL) {
        err("could not create pid file");
    } else {
        fprintf(fp, "%d", pid);
        fclose(fp);
    }

    // invoke the requirements checkers in the same order as on command line,
    // constructing the artifact tree originating at 'root'
    for (i = 0; i < ncmds; i++) {
        if (reqs[i].cmd->requirements != NULL) {
            art_set_instanceId(reqs[i].cmd->name);  // for logging
            if ((root = reqs[i].cmd->requirements(&reqs[i], root)) == NULL) // pass results of earlier checkers to later checkers
                err("failed while verifying requirements");
        }
    }

    // it is OK for root to be NULL at this point

    // see if work blobstore will be needed at any stage
    // and open or create the work blobstore
    if (root && tree_uses_blobstore(root)) {
        // set the function that will catch blobstore errors
        blobstore_set_error_function(&bs_errors);

        if (ensure_directories_exist(get_work_dir(), 0, NULL, NULL, BLOBSTORE_DIRECTORY_PERM) == -1)
            err("failed to open or create work directory %s", get_work_dir());

        work_bs = blobstore_open(get_work_dir(), get_work_limit() / 512, BLOBSTORE_FLAG_CREAT, BLOBSTORE_FORMAT_FILES, BLOBSTORE_REVOCATION_NONE, BLOBSTORE_SNAPSHOT_ANY);
        if (work_bs == NULL) {
            err("failed to open work blobstore: %s", blobstore_get_error_str(blobstore_get_error()));
        }
        // no point in fscking the work blobstore as it was just created
    }
    // see if cache blobstore will be needed at any stage
    if (root && tree_uses_cache(root)) {
        if (ensure_directories_exist(get_cache_dir(), 0, NULL, NULL, BLOBSTORE_DIRECTORY_PERM) == -1)
            err("failed to open or create cache directory %s", get_cache_dir());
        cache_bs = blobstore_open(get_cache_dir(), get_cache_limit() / 512, BLOBSTORE_FLAG_CREAT, BLOBSTORE_FORMAT_DIRECTORY, BLOBSTORE_REVOCATION_LRU, BLOBSTORE_SNAPSHOT_ANY);
        if (cache_bs == NULL) {
            blobstore_close(work_bs);
            err("failed to open cache blobstore: %s\n", blobstore_get_error_str(blobstore_get_error()));
        }

        if (blobstore_fsck(cache_bs, NULL)) //! @TODO: verify checksums?
            err("cache blobstore failed integrity check: %s", blobstore_get_error_str(blobstore_get_error()));

        if (stat_blobstore(get_cache_dir(), cache_bs))
            err("blobstore is unreadable");
    }
    // implement the artifact tree
    ret = EUCA_OK;
    if (root) {
        art_set_instanceId("imager");  // for logging
        ret = art_implement_tree(root, work_bs, cache_bs, NULL, INSTANCE_PREP_TIMEOUT_USEC);    // do all the work!
    }
    // invoke the cleaners for each command to tidy up disk space and memory allocations
    for (i = 0; i < ncmds; i++) {
        if (reqs[i].cmd->cleanup != NULL) {
            art_set_instanceId(reqs[i].cmd->name);  // for logging
            reqs[i].cmd->cleanup(&reqs[i], (i == (ncmds - 1)) ? (TRUE) : (FALSE));
        }
    }

    // free the artifact tree
    if (root) {
        if (tree_uses_blobstore(root)) {
            if (blobstore_fsck(work_bs, stale_blob_examiner)) { // will remove all blobs
                LOGWARN("failed to clean up work space: %s\n", blobstore_get_error_str(blobstore_get_error()));
            }
        }
        art_free(root);
    }
    clean_work_dir(work_bs);

    // indicate completion
    LOGINFO("imager done (exit code=%d)\n", ret);

    exit(ret);
}