int init_backing_store (const char * conf_instances_path, unsigned int conf_work_size_mb, unsigned int conf_cache_size_mb) { logprintfl (EUCAINFO, "initializing backing store...\n"); if (conf_instances_path == NULL) { logprintfl (EUCAERROR, "error: INSTANCE_PATH not specified\n"); return ERROR; } safe_strncpy (instances_path, conf_instances_path, sizeof (instances_path)); if (check_directory (instances_path)) { logprintfl (EUCAERROR, "error: INSTANCE_PATH (%s) does not exist!\n", instances_path); return ERROR; } char cache_path [MAX_PATH]; snprintf (cache_path, sizeof (cache_path), "%s/cache", instances_path); if (ensure_directories_exist (cache_path, 0, NULL, NULL, BACKING_DIRECTORY_PERM) == -1) return ERROR; char work_path [MAX_PATH]; snprintf (work_path, sizeof (work_path), "%s/work", instances_path); if (ensure_directories_exist (work_path, 0, NULL, NULL, BACKING_DIRECTORY_PERM) == -1) return ERROR; unsigned long long cache_limit_blocks = conf_cache_size_mb * 2048; // convert MB to blocks unsigned long long work_limit_blocks = conf_work_size_mb * 2048; if (work_limit_blocks==0) { // we take 0 as unlimited work_limit_blocks = ULLONG_MAX; } // by default we let blobstore pick the snapshot policy, which // will use device mapper if available, which is faster than copying blobstore_snapshot_t snapshot_policy = BLOBSTORE_SNAPSHOT_ANY; if (nc_state.disable_snapshots) { logprintfl (EUCAINFO, "if allocating storage, will avoid using snapshots\n"); snapshot_policy = BLOBSTORE_SNAPSHOT_NONE; } blobstore_set_error_function ( &bs_errors ); if (cache_limit_blocks) { cache_bs = blobstore_open (cache_path, cache_limit_blocks, BLOBSTORE_FLAG_CREAT, BLOBSTORE_FORMAT_DIRECTORY, BLOBSTORE_REVOCATION_LRU, snapshot_policy); if (cache_bs==NULL) { logprintfl (EUCAERROR, "ERROR: failed to open/create cache blobstore: %s\n", blobstore_get_error_str(blobstore_get_error())); return ERROR; } } work_bs = blobstore_open (work_path, work_limit_blocks, BLOBSTORE_FLAG_CREAT, BLOBSTORE_FORMAT_FILES, BLOBSTORE_REVOCATION_NONE, snapshot_policy); if (work_bs==NULL) { logprintfl (EUCAERROR, "ERROR: failed to open/create work blobstore: %s\n", blobstore_get_error_str(blobstore_get_error())); logprintfl (EUCAERROR, "ERROR: %s\n", blobstore_get_last_trace()); blobstore_close (cache_bs); return ERROR; } // set the initial value of the semaphore to the number of // disk-intensive operations that can run in parallel on this node if (nc_state.concurrent_disk_ops && (disk_sem = sem_alloc (nc_state.concurrent_disk_ops, "mutex")) == NULL) { logprintfl (EUCAERROR, "failed to create and initialize disk semaphore\n"); return ERROR; } return OK; }
//! //! Initialize the backing store. Called during initialization of node controller. //! //! @param[in] conf_instances_path path to where the instances information are stored //! @param[in] conf_work_size_mb the work blobstore size limit in MB (if 0 then unlimitted) //! @param[in] conf_cache_size_mb the cache blobstore size limit in MB (if 0 then cache isn't used) //! //! @return EUCA_OK on success or the following error codes: //! \li EUCA_INVALID_ERROR: if any parameter does not meet the preconditions //! \li EUCA_ACCESS_ERROR: if we fail to access our cache and work directories //! \li EUCA_PERMISSION_ERROR: if we fail to create the cache or work stores. //! //! @pre The conf_instances_path field must not be NULL //! //! @post On success, the backing store module is initialized and the following happened: //! \li our global instance_path variable is set with the given conf_instance_path //! \li the work blobstore is created and our global work_bs variable is set //! \li the cache blobstore is created if necessary and the cache_bs variable is set //! \li the disk semaphore is created if necessary //! int init_backing_store(const char *conf_instances_path, unsigned int conf_work_size_mb, unsigned int conf_cache_size_mb) { char cache_path[EUCA_MAX_PATH] = ""; char work_path[EUCA_MAX_PATH] = ""; unsigned long long cache_limit_blocks = 0; unsigned long long work_limit_blocks = 0; blobstore_snapshot_t snapshot_policy = BLOBSTORE_SNAPSHOT_ANY; LOGINFO("initializing backing store...\n"); // Make sure we have a valid intance path passed to us if (conf_instances_path == NULL) { LOGERROR("INSTANCE_PATH not specified\n"); return (EUCA_INVALID_ERROR); } // Set our global instance_path variable with the content of conf_instance_path euca_strncpy(instances_path, conf_instances_path, sizeof(instances_path)); if (check_directory(instances_path)) { LOGERROR("INSTANCE_PATH (%s) does not exist!\n", instances_path); return (EUCA_ACCESS_ERROR); } // Check if our cache path exist. If not it should get crated snprintf(cache_path, sizeof(cache_path), "%s/cache", instances_path); if (ensure_directories_exist(cache_path, 0, NULL, NULL, BACKING_DIRECTORY_PERM) == -1) return (EUCA_ACCESS_ERROR); // Check if our work path exist. If not it should get crated snprintf(work_path, sizeof(work_path), "%s/work", instances_path); if (ensure_directories_exist(work_path, 0, NULL, NULL, BACKING_DIRECTORY_PERM) == -1) return (EUCA_ACCESS_ERROR); // convert MB to blocks cache_limit_blocks = (unsigned long long)conf_cache_size_mb *2048; work_limit_blocks = (unsigned long long)conf_work_size_mb *2048; // we take 0 as unlimited if (work_limit_blocks == 0) { work_limit_blocks = ULLONG_MAX; } // by default we let blobstore pick the snapshot policy, which // will use device mapper if available, which is faster than copying snapshot_policy = BLOBSTORE_SNAPSHOT_ANY; if (nc_state.disable_snapshots) { LOGINFO("if allocating storage, will avoid using snapshots\n"); snapshot_policy = BLOBSTORE_SNAPSHOT_NONE; } // Set the backing store error callback function blobstore_set_error_function(&bs_errors); // Do we need to create a cache blobstore if (cache_limit_blocks) { cache_bs = blobstore_open(cache_path, cache_limit_blocks, BLOBSTORE_FLAG_CREAT, BLOBSTORE_FORMAT_DIRECTORY, BLOBSTORE_REVOCATION_LRU, snapshot_policy); if (cache_bs == NULL) { LOGERROR("failed to open/create cache blobstore: %s\n", blobstore_get_error_str(blobstore_get_error())); return (EUCA_PERMISSION_ERROR); } } // Lets open the work blobstore work_bs = blobstore_open(work_path, work_limit_blocks, BLOBSTORE_FLAG_CREAT, BLOBSTORE_FORMAT_FILES, BLOBSTORE_REVOCATION_NONE, snapshot_policy); if (work_bs == NULL) { LOGERROR("failed to open/create work blobstore: %s\n", blobstore_get_error_str(blobstore_get_error())); LOGERROR("%s\n", blobstore_get_last_trace()); BLOBSTORE_CLOSE(cache_bs); return (EUCA_PERMISSION_ERROR); } // set the initial value of the semaphore to the number of // disk-intensive operations that can run in parallel on this node if (nc_state.concurrent_disk_ops && ((disk_sem = sem_alloc(nc_state.concurrent_disk_ops, IPC_MUTEX_SEMAPHORE)) == NULL)) { LOGERROR("failed to create and initialize disk semaphore\n"); return (EUCA_PERMISSION_ERROR); } return (EUCA_OK); }