int zfork(){ ZRT_LOG(L_INFO, P_TEXT, "call zvm_fork"); /*zvm fork syscall here ...*/ int res = zvm_fork(); ZRT_LOG(L_INFO, "zvm_fork res=%d", res); /*update state for removable mounts, all removable mounts needs to be refreshed*/ get_fstab_observer()->reset_removable(HANDLE_ONLY_FSTAB_SECTION); /*re-read nvram file because after fork his content can be changed. */ /*Folowing nvram handlers using only stack and nor heap*/ struct NvramLoaderPublicInterface* nvram = INSTANCE_L(NVRAM_LOADER)(); /*if nvram config file not empty then do parsing*/ if ( nvram->read(nvram, DEV_NVRAM) > 0 ){ nvram->parse(nvram); /*handle debug section - verbosity*/ if ( NULL != nvram->section_by_name( nvram, DEBUG_SECTION_NAME ) ){ ZRT_LOG(L_INFO, "%s", "nvram handle debug"); nvram->handle(nvram, HANDLE_ONLY_DEBUG_SECTION, NULL, NULL, NULL ); } /*handle time section*/ if ( NULL != nvram->section_by_name( nvram, TIME_SECTION_NAME ) ){ nvram->handle(nvram, HANDLE_ONLY_TIME_SECTION, static_timeval(), NULL, NULL); } } ZRT_LOG(L_SHORT, "zfork() res=%d ", res); return res; }
struct MNvramObserver* get_fstab_observer(){ if ( s_inited_observer ) return s_inited_observer; struct MNvramObserver* self = &s_fstab_observer; ZRT_LOG(L_INFO, "Create observer for section: %s", FSTAB_SECTION_NAME); /*setup section name*/ strncpy(self->observed_section_name, FSTAB_SECTION_NAME, NVRAM_MAX_SECTION_NAME_LEN); /*setup section keys*/ keys_construct(&self->keys); /*add keys and check returned key indexes that are the same as expected*/ int key_index; /*check parameters*/ key_index = self->keys.add_key(&self->keys, FSTAB_PARAM_CHANNEL_KEY); assert(FSTAB_PARAM_CHANNEL_KEY_INDEX==key_index); key_index = self->keys.add_key(&self->keys, FSTAB_PARAM_MOUNTPOINT_KEY); assert(FSTAB_PARAM_MOUNTPOINT_KEY_INDEX==key_index); key_index = self->keys.add_key(&self->keys, FSTAB_PARAM_ACCESS_KEY); assert(FSTAB_PARAM_ACCESS_KEY_INDEX==key_index); key_index = self->keys.add_key(&self->keys, FSTAB_PARAM_REMOVABLE); assert(FSTAB_PARAM_REMOVABLE_KEY_INDEX==key_index); /*setup functions*/ s_fstab_observer.handle_nvram_record = handle_fstab_record; ZRT_LOG(L_SHORT, "OK observer for section: %s", FSTAB_SECTION_NAME); s_inited_observer = &s_fstab_observer; return s_inited_observer; }
/*fuse must use this function in own implementation, it's should always exist at least as stub, to get fuse library compiled*/ int fuse_main_common_implem(struct fuse_operations *op, const char *mountpoint, void *user_data){ #ifdef FUSEGLUE_EXT ZRT_LOG(L_SHORT, "Perform fuse mount and wait in thread, path=%s", mountpoint ); assert(s_fuse_mount_data!=NULL); struct async_lock_data *lock_data = match_mount_data_by_mountpoint(mountpoint); if (lock_data==NULL){ ZRT_LOG(L_ERROR, "Can't find fuse fs lock_data for mountpoint=%s", mountpoint ); assert(0); } /*perform filesystem mount here*/ int res = mount_fuse_fs(op, mountpoint, lock_data->args.expect_absolute_path, lock_data->args.proxy_mode); if (res != 0){ ZRT_LOG(L_ERROR, "Fuse fs mount error %d", res ); update_cond_value(lock_data, EConditionInitializationError); } else{ /*fuse init function*/ if ( op->init ){ lock_data->conn = calloc(1, sizeof(struct fuse_conn_info)); op->init(lock_data->conn); } /*when it finishes, update cond to continue zrt running*/ update_cond_value(lock_data, EConditionInitialized); /*wait here until exit*/ wait_cond_value_less_than_expected(lock_data, EConditionWaitingFinalization); } ZRT_LOG(L_SHORT, "Finalize fuse mount, err=%d, path=%s", res, mountpoint ); return res; #else return -1; #endif /*FUSEGLUE_EXT*/ }
struct MountInfo* mm_mountinfo_bypath( struct MountsManager *mounts_manager, const char* path, int *mount_index ){ struct MountInfo *mount_info=NULL; int i; for( i=0; i < mounts_manager->mount_items.num_entries; i++ ){ /*if matched path and mount path*/ struct MountInfo *current_mount_info = (struct MountInfo *)DynArrayGet(&mounts_manager->mount_items, i); if ( current_mount_info == NULL ) continue; const char* mount_path = current_mount_info->mount_path; /*if path is matched, then check mountpoint*/ if ( !strncmp( mount_path, path, strlen(mount_path) ) ){ if ( mount_info == NULL || strlen(mount_path) > strlen(mount_info->mount_path) ){ mount_info = current_mount_info; *mount_index=i; } } } if ( mount_info != NULL ){ ZRT_LOG(L_EXTRA, "located mount by path=%s: mountpoint=%s, mount_index=%d", path, mount_info->mount_path, *mount_index); return mount_info; } else{ ZRT_LOG(L_EXTRA, "didn't locate mount by path=%s", path); return NULL; } }
void handle_mount_import(struct FstabObserver* observer, struct FstabRecordContainer* record){ assert(s_channels_mount != NULL); assert(s_transparent_mount != NULL); if ( record != NULL ){ /*get all params*/ char* channel_alias = NULL; char* mount_path = NULL; char* access = NULL; char* removable = NULL; char* fsname = NULL; GET_FSTAB_PARAMS(&record->mount, &channel_alias, &mount_path, &access, &removable, &fsname); int removable_record = !strcasecmp( removable, FSTAB_VAL_REMOVABLE_YES); /* In case if we need to inject files into FS.*/ if ( !strcmp(access, FSTAB_VAL_ACCESS_READ) && EFstabMountWaiting == record->mount_status && ( removable_record || (!s_updated_fstab_records && !removable_record) ) ){ /* * inject tar contents related to record into mount_path folder of filesystem; * Content of filesystem is reading from supported archive type linked to channel, * currently TAR can be mounted, into MemMount filesystem */ ZRT_LOG(L_SHORT, "mount now: channel=%s, mount_path=%s, access=%s, removable=%s, fsname=%s", channel_alias, mount_path, access, removable, fsname); record->mount_status = EFstabMountProcessing; /*create mounts reader linked to tar archive that contains filesystem image, it call "read" from MountsPublicInterface and don't call "read" function from posix layer*/ struct MountsReader* mounts_reader = alloc_mounts_reader( s_channels_mount, channel_alias ); if ( mounts_reader ){ /*create image loader, passed 1st param: image alias, 2nd param: Root filesystem; * Root filesystem passed instead MemMount to reject adding of files into /dev folder; * For example if archive contains non empty /dev folder that contents will be ignored*/ struct ImageInterface* image_loader = alloc_image_loader( s_transparent_mount ); /*create archive unpacker*/ struct UnpackInterface* tar_unpacker = alloc_unpacker_tar( mounts_reader, image_loader->observer_implementation ); /*read archive from linked channel and add all contents into Filesystem*/ int inject_res = image_loader->deploy_image( mount_path, tar_unpacker ); record->mount_status = EFstabMountComplete; if ( inject_res >=0 ){ ZRT_LOG( L_SHORT, "From %s archive readed and injected %d files " "into %s folder of ZRT filesystem", channel_alias, inject_res, mount_path ); } else{ ZRT_LOG( L_ERROR, "Error %d occured while injecting files from %s archive", inject_res, channel_alias ); } free_unpacker_tar( tar_unpacker ); free_image_loader( image_loader ); free_mounts_reader( mounts_reader ); } } } }
int exec_fuse_main(const char *mountpoint, int expect_absolute_path, char proxy_mode, int (*fs_main)(int, char**), int fs_argc, char **fs_argv){ int res=0; /*create mounts data array*/ if ( s_fuse_mount_data == NULL ){ s_fuse_mount_data = calloc(1, sizeof(struct DynArray)); DynArrayCtor( s_fuse_mount_data, 2 /*granularity*/ ); } /*prepare parameters for thread function*/ struct async_lock_data *lock_data = calloc(1, sizeof(struct async_lock_data)); strncpy(lock_data->args.mountpoint, mountpoint, sizeof(lock_data->args.mountpoint) ); strncpy(lock_data->name, mountpoint, sizeof(lock_data->name) ); lock_data->args.expect_absolute_path = expect_absolute_path; lock_data->args.proxy_mode = proxy_mode; lock_data->args.mount_argc = fs_argc; lock_data->args.mount_argv = fs_argv; lock_data->args.mount_main = fs_main; lock_data->mutex = PTHREAD_MUTEX_INITIALIZER; lock_data->cond = PTHREAD_COND_INITIALIZER; lock_data->cond_value = EConditionWaitingInitialization; /*add to array*/ if (! DynArraySet( s_fuse_mount_data, s_fuse_mount_data->num_entries, lock_data )){ /*error adding to array*/ ZRT_LOG(L_ERROR, "Error adding fuse mount data with mountpoint %s", mountpoint ); free(lock_data); return -1; } /*save array index of just added lock_data*/ lock_data->index = s_fuse_mount_data->num_entries-1; pthread_t thread_create_fuse; if (pthread_create(&thread_create_fuse, NULL, exec_fuse_main_async, lock_data) != 0){ return -1; } /*Wait here for condition while fuse fs will not be created successfully or will raise an error*/ wait_cond_value_less_than_expected( lock_data, EConditionInitializationError); if ( match_cond_value(lock_data, EConditionInitializationError) ){ /*File system init error*/ res=-1; } else{ /*Wait while filesystem initialization is done, it is signalled by lock_data.cond. It is expected fuse_main to be called inside mount_main, and then it releases condition below*/ wait_cond_value_less_than_expected( lock_data, EConditionInitialized); ZRT_LOG(L_INFO, "%s", "fuse fs initializer finished" ); res=0; } /*keep all data allocated until EConditionWaitingFinalization*/ return res; }
/*low level function, copy dirent args into buf*/ static ssize_t put_dirent_into_buf( char *buf, int buf_size, unsigned long d_ino, unsigned long d_off, unsigned long mode, const char *d_name ){ DIRENT *dirent = (DIRENT *) buf; ZRT_LOG(L_EXTRA, "dirent offset: ino_off=%u, off_off=%u, reclen_off=%u, name_off=%u", offsetof( DIRENT, d_ino ), offsetof( DIRENT, d_off ), offsetof( DIRENT, d_reclen ), offsetof( DIRENT, d_name ) ); int namelength = strlen(d_name); size_t adjusted_size = adjusted_dirent_size(namelength); /*if size of the current dirent data is less than available buffer size then fill it by data*/ if ( adjusted_size <= buf_size ){ dirent->d_reclen = adjusted_size; dirent->d_ino = d_ino; #ifdef ZRTDIRENT dirent->d_type = d_type_from_mode(mode); #endif //ZRTDIRENT if ( d_off == 0x7fffffff ) dirent->d_off = 0x7fffffff; else dirent->d_off = d_off+dirent->d_reclen; memcpy( dirent->d_name, d_name, namelength ); ((char*)dirent->d_name)[namelength] = '\0'; ZRT_LOG(L_SHORT, "dirent: name=%s, ino=%u, d_off=%u, d_reclen=%d " #ifdef ZRTDIRENT ", d_type=%d" #endif ,d_name, (unsigned int)d_ino, (unsigned int)d_off, dirent->d_reclen #ifdef ZRTDIRENT ,dirent->d_type #endif ); return dirent->d_reclen; } /*buffer is not enough to save current dirent structure*/ else{ ZRT_LOG(L_EXTRA, "no enough buffer, " "data_size=%d, buf_size=%d", adjusted_size, buf_size); return -1; /*no enough buffer size*/ } }
void update_cond_value(struct async_lock_data * lock_data, int new_cond_value) { pthread_mutex_lock( &lock_data->mutex ); ZRT_LOG(L_INFO, "update condition='%s' current value=%d, new value=%d", lock_data->name, lock_data->cond_value, new_cond_value ); lock_data->cond_value = new_cond_value; pthread_cond_signal( &lock_data->cond ); ZRT_LOG(L_INFO, "update condition='%s' current value=%d, new value=%d", lock_data->name, lock_data->cond_value, new_cond_value ); pthread_mutex_unlock( &lock_data->mutex ); }
/*wait while cond value is LESS THAN expected*/ void wait_cond_value_less_than_expected(struct async_lock_data * lock_data, int expected_cond_value) { pthread_mutex_lock( &lock_data->mutex ); ZRT_LOG(L_INFO, "condition='%s' current value=%d, wait value=%d", lock_data->name, lock_data->cond_value, expected_cond_value ); while( lock_data->cond_value < expected_cond_value ) pthread_cond_wait( &lock_data->cond, &lock_data->mutex ); pthread_cond_signal( &lock_data->cond ); ZRT_LOG(L_INFO, "condition='%s' new value=%d", lock_data->name, lock_data->cond_value ); pthread_mutex_unlock( &lock_data->mutex ); }
/*unpack observer 1st parameter : main unpack interface that gives access to observer, stream and mounted fs*/ static int extract_entry( struct UnpackInterface* unpacker, TypeFlag type, const char* name, int entry_size ){ /*parse path and create directories recursively*/ ZRT_LOG( L_INFO, "type=%s, name=%s, entry_size=%d", STR_ARCH_ENTRY_TYPE(type), name, entry_size ); /*setup path parser observer *observers callback will be called for every paursed subdir extracted from full path*/ struct ParsePathObserver path_observer; path_observer.callback_parse = callback_parse; path_observer.anyobj = unpacker->observer->mounts; /*run path parser*/ int parsed_dir_count = parse_path( &path_observer, name ); ZRT_LOG(L_INFO, "parsed_dir_count=%d", parsed_dir_count ); if ( type == ETypeDir ){ create_dir_and_cache_name(name, strlen(name)); } else{ int out_fd = unpacker->observer->mounts->open(name, O_WRONLY | O_CREAT, S_IRWXU); if (out_fd < 0) { ZRT_LOG( L_ERROR, "create new file error, name=%s", name ); return -1; } int should_write = entry_size; int write_err = 0; /*read file by blocks*/ while (entry_size > 0) { int len = (*unpacker->stream_reader->read)( unpacker->stream_reader, block, sizeof(block) ); if (len != sizeof(block)) { ZRT_LOG(L_ERROR, "read error. current file can't be saved name=%s", name); return -1; } int wrote; if (entry_size > sizeof(block)) { WRITE_FILE( &wrote, &write_err, out_fd, block, sizeof(block) ); } else { WRITE_FILE( &wrote, &write_err, out_fd, block, entry_size ); } if ( write_err ){ return -1; } entry_size -= sizeof(block); } ZRT_LOG(L_SHORT, "%7d B saved : %s", should_write, name); unpacker->observer->mounts->close(out_fd); } return 0; }
int zrt_zcall_enhanced_open(const char *name, int flags, mode_t mode, int *newfd){ LOG_SYSCALL_START("name=%s flags=%d mode=%o(octal)", name, flags, mode ); char* absolute_path; char temp_path[PATH_MAX]; int ret=-1; errno=0; VALIDATE_SYSCALL_PTR(name); /*reset mode bits, that is not actual for permissions*/ mode&=(S_IRWXU|S_IRWXG|S_IRWXO); APPLY_UMASK(&mode); if ( (absolute_path = zrealpath(name, temp_path)) != NULL ){ ZRT_LOG(L_SHORT, "absolute_path=%s", absolute_path); if ( (ret = s_transparent_mount->open(s_transparent_mount, absolute_path, flags, mode )) >= 0 ){ /*get fd by pointer*/ *newfd = ret; ret =0; } } LOG_SHORT_SYSCALL_FINISH( ret, "*newfd=%d, name=%s, flags=%s, mode=%s", *newfd, name, STR_ALLOCA_COPY(STR_FILE_OPEN_FLAGS(flags)), STR_ALLOCA_COPY(STR_STAT_ST_MODE(mode))); return ret; }
static struct ParsedRecord* get_parsed_record(struct ParsedRecord* record, const struct KeyList* keys, struct internal_parse_data* params_array, int params_count){ assert(keys); int i; for(i=0; i < params_count; i++ ){ /*if key matched it return key index, in specified list of expecting keys so it's *guarantied that key always has determinded index even for unspecified their order*/ int key_index = keys->find(keys, params_array[i].key, params_array[i].keylen); /*if current key is wrong*/ if ( key_index < 0 ){ #ifdef PARSER_DEBUG_LOG ZRT_LOG(L_ERROR, "invalid key '%s'", GET_STRING(params_array[i].key, params_array[i].keylen ) ); #endif return NULL; /*error*/ } else{ /*save current param*/ record->parsed_params_array[key_index].key_index = key_index; /*param index*/ record->parsed_params_array[key_index].val = params_array[i].val; record->parsed_params_array[key_index].vallen = params_array[i].vallen; } } return record; }
/*get pointer to file structure *substitude glibc implementation */ FILE *fdopen(int fd, const char *mode){ LOG_SYSCALL_START("fd=%d mode=%s", fd, mode); FILE* f = NULL; struct MountsManager* mm = mounts_manager(); /*get access to main mounts object*/ struct MountsInterface* mif = mm->mount_byhandle(fd); /*get valid mount or NULL*/ if ( mif ){ struct mount_specific_implem* implem = mif->implem(); assert(implem); /*mount specific implem can't be NULL*/ /*check if handle has appropriate path*/ const char* path = implem->handle_path(fd); /*run fopen with path parameter instead fd handle*/ if ( path ){ ZRT_LOG(L_SHORT, "fopen(path:%s, mode:%s)", path, mode); f = fopen(path, mode); } } if ( f == NULL ){ SET_ERRNO(EBADF); } LOG_SYSCALL_FINISH( (f==NULL), "fd=%d mode=%s", fd, mode ); return f; }
/* check path directory is cached or not. * it's extract part related to full directory name from path and compare it * to previously cached dir name that's already created on filesystem. * @param path to check * @return 0 if cached, -1 if not; * */ int create_dir_and_cache_name( const char* dirpath, int len ){ int res = strncmp( dirpath, s_cached_full_path, len) == 0? 0: 1; if ( res != 0 ){ /*reset old cache and save path in cache*/ memset(s_cached_full_path, '\0', sizeof(s_cached_full_path)); strncpy( s_cached_full_path, dirpath, len ); /* create dir*/ int ret = mkdir( s_cached_full_path, S_IRWXU ); if ( ret != 0 && errno != EEXIST ){ /*error while creating dir, new path handled, cache not saved, *it is needed to create sub dir previously*/ memset(s_cached_full_path, '\0', sizeof(s_cached_full_path)); res = -1; /*new path handled, cache not saved*/ } else{ /*directory exist*/ res = 0; } ZRT_LOG(L_EXTRA, "mkdir errno=%d, ret=%d: %s", errno, ret, s_cached_full_path); } else{ /*path already handled*/ } return res; }
static int get_inode(int handle, ino_t* inode ){ CHECK_HANDLE(handle); ZRT_LOG( L_EXTRA, "handle=%d, inode=%d, inode pointer=%p", handle, (int)s_handle_slots[handle].inode, &(s_handle_slots[handle]).inode ); *inode = s_handle_slots[handle].inode; return 0; }
void buf_flush_write( BufferedIOWrite* self, int handle ){ if ( self->data.cursor ){ int b = self->write_override(handle, self->data.buf, self->data.cursor); ZRT_LOG(L_EXTRA, "buffered_io: flush %d/%d bytes \n", b, self->data.cursor ); self->data.cursor = 0; } }
static int fuse_operations_mount_ftruncate_size(struct MountsPublicInterface* this_, int fd, off_t length) { int ret; struct FuseOperationsMount* fs = (struct FuseOperationsMount*)this_; const struct OpenFileDescription* ofd = fs->handle_allocator->ofd(fd); if (ofd==NULL) { SET_ERRNO(ENOENT); return -1; } struct FuseFileOptionalData *fdata = (struct FuseFileOptionalData *)ofd->optional_data; struct stat st; CHECK_FUNC_ENSURE_EXIST(fs, ftruncate); GET_STAT_ENSURE_EXIST(fs, fdata->path, &st); if ( S_ISDIR(st.st_mode) ) { SET_ERRNO(EISDIR); return -1; } int flags = ofd->flags & O_ACCMODE; /*check if file was not opened for writing*/ if ( flags!=O_WRONLY && flags!=O_RDWR ) { ZRT_LOG(L_ERROR, "file open flags=%s not allow truncate", STR_FILE_OPEN_FLAGS(flags)); SET_ERRNO( EINVAL ); return -1; } if ( (ret=fs->fuse_operations->ftruncate(fdata->path, length, fdata->finfo )) < 0 ) { SET_ERRNO(-ret); return -1; } return ret; }
/* * exit. without it the user program cannot terminate correctly. */ void zrt_zcall_enhanced_exit(int status){ ZRT_LOG(L_SHORT, "status %d exiting...", status); get_fstab_observer()->mount_export(HANDLE_ONLY_FSTAB_SECTION); zvm_exit(status); /*get controls into zerovm*/ /* unreachable code*/ return; }
int zrt_zcall_ftruncate(int fd, off_t length){ CHECK_EXIT_IF_ZRT_NOT_READY; LOG_SYSCALL_START("fd=%d,length=%lld", fd, length); struct MountsPublicInterface* transpar_mount = transparent_mount(); assert(transpar_mount); errno=0; int ret; off_t saved_pos; struct stat st; /*save file position*/ saved_pos = lseek( fd, 0, SEEK_CUR); CHECK_NON_NEGATIVE_VALUE_RETURN_ERROR(saved_pos); /*get end pos of file*/ ret = fstat(fd, &st); assert(ret==0); CHECK_NON_NEGATIVE_VALUE_RETURN_ERROR(st.st_size); /*if filesize should be increased then just write null bytes '\0' into*/ if ( length > st.st_size ){ /*set cursor to the end of file, and check assertion*/ off_t endpos = lseek( fd, st.st_size, SEEK_SET); CHECK_NON_NEGATIVE_VALUE_RETURN_ERROR(st.st_size); assert(endpos==st.st_size); /*just write amount of bytes starting from end of file*/ int res = write_file_padding(fd, length-st.st_size); CHECK_NON_NEGATIVE_VALUE_RETURN_ERROR(res); } else{ /*truncate data if user wants to reduce filesize *set new file size*/ int res = transpar_mount->ftruncate_size(transpar_mount, fd, length); CHECK_NON_NEGATIVE_VALUE_RETURN_ERROR(res); } /*restore file position, it's should stay unchanged*/ if ( saved_pos < length ){ LSEEK_SET_ASSERT_IF_FAIL(fd, saved_pos); } else if (saved_pos > length){ /*it is impossible to restore oldpos because it's not valid anymore *it's pointing beyond of the file*/ } /*final check of real file size and expected size*/ ret = fstat(fd, &st); assert(ret==0); ZRT_LOG(L_INFO, "real truncated file size is %lld", st.st_size ); assert(st.st_size==length); LOG_SHORT_SYSCALL_FINISH( 0, "fd=%d, old_length=%lld,new_length=%lld", fd, st.st_size, length); return 0; }
/*interface function while handling data it's saving it to buffer provided in obj1 and updating used buffer space (index) in obj3 param*/ void handle_env_record(struct MNvramObserver* observer, struct ParsedRecord* record, void* obj1, void* obj2, void* obj3){ assert(record); /*get param*/ char* envname = NULL; ALLOCA_PARAM_VALUE(record->parsed_params_array[ENV_PARAM_NAME_KEY_INDEX], &envname); /*get param*/ char* envval = NULL; ALLOCA_PARAM_VALUE(record->parsed_params_array[ENV_PARAM_VALUE_KEY_INDEX], &envval); ZRT_LOG(L_INFO, "env record: %s=%s", envname, envval); /*unescape value*/ char* unescaped_value_result = alloca( strlen(envval)+1 ); int unescaped_value_len = unescape_string_copy_to_dest(envval, record->parsed_params_array[ENV_PARAM_VALUE_KEY_INDEX].vallen, unescaped_value_result); ZRT_LOG(L_SHORT, "env record: %s=%s (escaped) %d", envname, unescaped_value_result, unescaped_value_len); /*If handling envs at session start preparing main() arguments, it's expected code running at prolog stage*/ if ( obj1 && obj2 && obj3 ){ char* buffer = (char*)obj1; /*obj1 - char* */ int bufsize = *(int*)obj2; /*obj2 - int* */ int* index = (int*)obj3; /*obj3 - int* */ assert(buffer); /*into buffer will be saved results*/ add_pair_to_temp_buffer(buffer, bufsize, index, envname, record->parsed_params_array[ENV_PARAM_NAME_KEY_INDEX].vallen, unescaped_value_result, unescaped_value_len); } /*Handling envs at forked session, no another input parameters needed */ else{ if ( setenv(envname, unescaped_value_result, 1) == 0 ){ ZRT_LOG(L_INFO, P_TEXT, "env overwrite success"); } else{ ZRT_LOG(L_INFO, P_TEXT, "env overwrite failed"); } } }
static int add_key_to_list(struct KeyList* list, const char* key){ assert(list); /*copy key up to maximum length*/ strncpy( list->keys[list->count], key, NVRAM_MAX_KEY_LENGTH ); ZRT_LOG(L_INFO, "%s", key); /*if folowing assert is raised then just increase NVRAM_MAX_KEYS_COUNT_IN_RECORD value*/ assert(list->count<NVRAM_MAX_KEYS_COUNT_IN_RECORD); return list->count++; /*get index of added key*/ }
struct MNvramObserver* get_precache_observer(){ struct MNvramObserver* self = &s_precache_observer; ZRT_LOG(L_INFO, "Create observer for section: %s", PRECACHE_SECTION_NAME); /*setup section name*/ strncpy(self->observed_section_name, PRECACHE_SECTION_NAME, NVRAM_MAX_SECTION_NAME_LEN); /*setup section keys*/ keys_construct(&self->keys); /*add keys and check returned key indexes that are the same as expected*/ int key_index; /*check parameters*/ key_index = self->keys.add_key(&self->keys, PRECACHE_PARAM_PRECACHE_KEY); assert(PRECACHE_PARAM_PRECACHE_KEY_INDEX==key_index); /*setup functions*/ s_precache_observer.handle_nvram_record = handle_precache_record; ZRT_LOG(L_SHORT, "OK observer for section: %s", PRECACHE_SECTION_NAME); return &s_precache_observer; }
char *getcwd(char *buf, size_t size) { if ( !buf ) return NULL; ZRT_LOG(L_SHORT, "buf=%s, size=%d", buf, size); /*buf size is not enough */ if ( size < sizeof DEFAULT_WORKING_DIRPATH ){ SET_ERRNO(ERANGE); } /*buf size is enough to set path "/" */ else{ /*copy into buffer exactly dir of the specified size*/ strcpy(buf, DEFAULT_WORKING_DIRPATH); } ZRT_LOG(L_SHORT, "return buf=%s, len=%d", buf, strlen(DEFAULT_WORKING_DIRPATH) ); return buf; }
int AddAllChannelsRelatedToNodeTypeFromDir( struct ChannelsConfigInterface *chan_if, const char *dirpath, int channel_mode, int nodetype, const char* nodename_text ){ int res=0; int extracted_len; int extracted_nodeid=0; const char *readdir_get_name = NULL; int fd=-1; /*********************************************************************** open in channel, readed from /dev/in dir */ ZRT_LOG(L_SHORT, "Add directory=%s content items matched by pattern=%s", dirpath, nodename_text); DIR *dp = opendir( dirpath ); while ( (readdir_get_name=listdir(dp)) && !res ){ /*fetch node type name and node identifier*/ extracted_nodeid = ExtractNodeNameId( readdir_get_name, &extracted_len ); /*if iterated directory item matched with nodename pattern *then extract handle of that directory item by opening of it's file *and add it to channels config*/ ZRT_LOG(L_EXTRA, "directory item=%s, len=%d", readdir_get_name, extracted_len ); if ( extracted_len == strlen(nodename_text) && !strncmp(nodename_text, readdir_get_name, extracted_len ) ) { snprintf( s_temp_path, MAX_PATH_LENGTH, "%s/%s", dirpath, readdir_get_name ); if ( channel_mode == EChannelModeWrite ) fd = open( s_temp_path, O_WRONLY); /*open channel fetched from manifest configuration*/ else fd = open( s_temp_path, O_RDONLY); /*open channel fetched from manifest configuration*/ ZRT_LOG(L_SHORT, "matched item=%s by pattern=%s", readdir_get_name, nodename_text); assert(fd>=0); if ( extracted_nodeid == -1 ) extracted_nodeid = 1; /*for single node without id*/ if( chan_if->AddChannel( chan_if, nodetype, extracted_nodeid, fd, channel_mode ) == NULL ){ res=-1; break; } } } closedir(dp); ZRT_LOG(L_SHORT, "channels added to config, res=%d by pattern=%s", res, nodename_text); return res; }
struct passwd* getpwuid(uid_t uid) { ZRT_LOG(L_SHORT, "uid=%u", uid); if ( uid == 1 ) return &s_passwd_data_1; else{ SET_ERRNO(ENOENT); /*uid mismatch*/ } return NULL; }
static int add_key_to_list(struct KeyList* list, const char* key, const char* optional_default_value){ assert(list); /*copy key up to maximum length*/ list->keys[list->count] = key; list->optional_default_values[list->count] = optional_default_value; ZRT_LOG(L_INFO, "%s, optional=%s", key, optional_default_value); /*if folowing assert is raised then just increase NVRAM_MAX_KEYS_COUNT_IN_RECORD value*/ assert(list->count<NVRAM_MAX_KEYS_COUNT_IN_RECORD); return list->count++; /*get index of added key*/ }
void zrt_internal_session_info( const struct UserManifest const* manifest ){ int i; char **envp = environ; time_t t = time(NULL); int pages_count = (int)(manifest->heap_size / sysconf(_SC_PAGE_SIZE)); LOG_DEBUG(ELogTitle, "ZVM SESSION INFO", "=======") LOG_DEBUG(ELogAddress, (intptr_t)manifest->heap_ptr, "ZVM Manifest heap pointer" ) LOG_DEBUG(ELogSize, manifest->heap_size, "ZVM Manifest heap size" ) /*get from system, print environment variables*/ LOG_DEBUG(ELogTime, ctime(&t), "System time" ) LOG_DEBUG(ELogSize, sysconf(_SC_PAGE_SIZE), "Page size _SC_PAGE_SIZE" ) LOG_DEBUG(ELogCount, pages_count, "Memory pages count" ) LOG_DEBUG(ELogAddress, manifest->heap_ptr + manifest->heap_size, "Heap highest page" ) LOG_DEBUG(ELogAddress, sbrk(0), "sbrk(0)" ) LOG_DEBUG(ELogTitle, "Environment variables", "======") i=0; while( envp[i] ){ ZRT_LOG(L_BASE, "envp[%d] = '%s'", i, envp[i]); ++i; } LOG_DEBUG(ELogCount, manifest->channels_count, "channels list") /*print channels list*/ for(i = 0; i < manifest->channels_count; ++i) { ZRT_LOG(L_BASE, "channel[%2d].name = '%s'", i, manifest->channels[i].name); ZRT_LOG(L_BASE, "channel[%2d].type=%d, size=%lld", i, manifest->channels[i].type, manifest->channels[i].size); ZRT_LOG(L_BASE, "channel[%2d].limits[GetsLimit=%7lld, GetSizeLimit=%7lld]", i, manifest->channels[i].limits[GetsLimit], manifest->channels[i].limits[GetSizeLimit]); ZRT_LOG(L_BASE, "channel[%2d].limits[PutsLimit=%7lld, PutSizeLimit=%7lld]", i, manifest->channels[i].limits[PutsLimit], manifest->channels[i].limits[PutSizeLimit]); } }
int seek_unused_slot( int starting_from ){ int i; starting_from = starting_from<0 ?0 :starting_from; for ( i=starting_from; i < MAX_HANDLES_COUNT; i++ ){ if ( s_handle_slots[i].used == EHandleAvailable ){ /*found closest unusable slot*/ ZRT_LOG( L_INFO, "slot index=%d, EHandleAvailable", i ); s_first_unused_slot = i; return s_first_unused_slot; } } return -1; }
static int transparent_fcntl(int fd, int cmd, ...){ int ret=0; struct MountsInterface* mount = s_mounts_manager->mount_byhandle(fd); if ( mount ){ va_list args; if ( cmd == F_SETLK || cmd == F_SETLKW || cmd == F_GETLK ){ va_start(args, cmd); struct flock* input_lock = va_arg(args, struct flock*); ZRT_LOG(L_SHORT, "flock=%p", input_lock ); if ( 0 == (ret=mount->fcntl(fd, cmd, input_lock)) ){ ret = fcntl_implem(mount->implem(), fd, cmd, input_lock); } va_end(args); } else if( cmd == F_GETFL ){
void __zrt_log_pop_name( const char* expected_name ) { #ifdef LOG_FUNCTION_STACK_NAMES if ( !s_log_enabled ) return ; /*logging switched off*/ char *s = strrchr(s_nested_syscalls_str, ' '); if ( s ){ const char* actual_name = s+1; if (strcmp(expected_name, actual_name)){ ZRT_LOG(L_ERROR, "expected_name=%s, actual_name=%s", expected_name, actual_name); /*check if popped name is equal to expectations*/ assert( !strcmp(expected_name, actual_name) ); } s[0] = '\0'; } #endif }