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 ); } } } }
void handle_fstab_record(struct MNvramObserver* observer, struct ParsedRecord* record, void* obj1, void* obj2, void* obj3){ assert(record); /*obj1 - only channels filesystem interface*/ struct MountsInterface* channels_mount = (struct MountsInterface*)obj1; /*obj2 - whole filesystem interface*/ struct MountsInterface* transparent_mount = (struct MountsInterface*)obj2; /*handle record according to removable state*/ int fstab_mount_stage = (int)obj3; /*get param*/ char* channel_alias = NULL; ALLOCA_PARAM_VALUE(record->parsed_params_array[FSTAB_PARAM_CHANNEL_KEY_INDEX], &channel_alias); /*get param*/ char* mount_path = NULL; ALLOCA_PARAM_VALUE(record->parsed_params_array[FSTAB_PARAM_MOUNTPOINT_KEY_INDEX], &mount_path); /*get param check*/ char* access = NULL; ALLOCA_PARAM_VALUE(record->parsed_params_array[FSTAB_PARAM_ACCESS_KEY_INDEX], &access); /*get param check*/ char* removable = NULL; ALLOCA_PARAM_VALUE(record->parsed_params_array[FSTAB_PARAM_REMOVABLE_KEY_INDEX], &removable); int removable_record = !strcasecmp( removable, FSTAB_VAL_REMOVABLE_YES); ZRT_LOG(L_SHORT, "fstab record handle now=%d: channel=%s, mount_path=%s, access=%s, removable=%s", IS_NEED_TO_HANDLE_FSTAB_RECORD(fstab_mount_stage, removable_record), channel_alias, mount_path, access, removable); /* In case if we need to inject files into FS.*/ if ( !strcmp(access, FSTAB_VAL_ACCESS_READ) && IS_NEED_TO_HANDLE_FSTAB_RECORD(fstab_mount_stage, removable_record) ){ /* * inject contents into specified folder mount_path of filesystem, from channel name * channel_alias. Content of filesystem is reading from channel that points to * supported archive, tar currently, read every file dir and add it into MemMount filesystem */ /*create mounts reader linked to tar archive that contains filesystem image, it call "read" from MountsInterface and don't call "read" function from posix layer*/ struct MountsReader* mounts_reader = alloc_mounts_reader( 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( 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 count_files = image_loader->deploy_image( mount_path, tar_unpacker ); ZRT_LOG( L_SHORT, "From %s archive readed and injected %d files " "into %s folder of ZRT filesystem", channel_alias, count_files, mount_path ); free_unpacker_tar( tar_unpacker ); free_image_loader( image_loader ); free_mounts_reader( mounts_reader ); } } #ifdef FSTAB_SAVE_TAR_ENABLE /*save files located at mount_path into tar archive*/ else if ( !strcmp(access, FSTAB_VAL_ACCESS_WRITE) ){ /*as temp solution, need to do good solution to export tar*/ memset(&s_export_tarrecords, '\0', sizeof(s_export_tarrecords)); struct ParsedRecord* record = &s_export_tarrecords.records[s_export_tarrecords.count]; struct ParsedParam* p1 = &record->parsed_params_array[FSTAB_PARAM_CHANNEL_KEY_INDEX]; struct ParsedParam* p2 = &record->parsed_params_array[FSTAB_PARAM_MOUNTPOINT_KEY_INDEX]; p1->key_index = FSTAB_PARAM_CHANNEL_KEY_INDEX; p1->val = strdup(channel_alias); p1->vallen = strlen(channel_alias); p2->key_index = FSTAB_PARAM_MOUNTPOINT_KEY_INDEX; p2->val = strdup(mount_path); p2->vallen = strlen(mount_path); s_export_tarrecords.count++; ZRT_LOG( L_SHORT, "Export scheduled on exit from '%s' into channel '%s'", mount_path, channel_alias); } #endif //FSTAB_SAVE_TAR_ENABLE ZRT_LOG_DELIMETER; }