int dfs_elm_unmount(struct dfs_filesystem *fs) { FATFS *fat; FRESULT result; int index; fat = (FATFS *)fs->data; RT_ASSERT(fat != RT_NULL); /* find the device index and then umount it */ index = get_disk(fs->dev_id); if (index == -1) /* not found */ return -DFS_STATUS_ENOENT; result = f_mount(RT_NULL, "", (BYTE)index); if (result != FR_OK) return elm_result_to_dfs(result); fs->data = RT_NULL; disk[index] = RT_NULL; rt_free(fat); return DFS_STATUS_OK; }
void stheno_add_card(void) { struct kobject* kobj; static char env_major[32]; char* env[16]; int i; if (!stheno_gd) return; kobj = get_disk(stheno_gd); if (!kobj) return; sprintf(env_major, "MAJOR=%d", stheno_major); i = 0; env[i++] = env_major; env[i++] = "MINOR=0"; env[i++] = "DEVNAME=stheno"; env[i++] = "DEVTYPE=disk"; env[i++] = "NPARTS=1"; env[i++] = NULL; kobject_uevent_env(kobj, KOBJ_ADD, env); i = 0; env[i++] = env_major; env[i++] = "MINOR=0"; env[i++] = "DEVNAME=stheno"; env[i++] = "DEVTYPE="; env[i++] = "PARTN=1"; env[i++] = NULL; kobject_uevent_env(kobj, KOBJ_ADD, env); put_disk(stheno_gd); }
// Go home and retrieve disk void get_disk() { int try_counter = 0; left_home(); delay(1000); down_seek(50, 1); pump(ON); delay(2000); lift_arm(); delay(500); if (digitalRead(ACTUATOR_LIMIT) == HIGH) { delay(50); if (digitalRead(ACTUATOR_LIMIT) == HIGH) { get_disk(); retry_counter++; if (retry_counter > MAX_RETRIES) { reportError("No Disk"); exit; } } } }
static int exact_lock(dev_t dev, void *data) { struct gendisk *p = data; if (!get_disk(p)) return -1; return 0; }
/* * Iterates through each available disk on the system. For each free * dmgt_disk_t *, runs the given function with the dmgt_disk_t * as * the first arg and the given void * as the second arg. */ int dmgt_avail_disk_iter(dmgt_disk_iter_f func, void *data) { int error = 0; int filter[] = { DM_DT_FIXED, -1 }; /* Search for fixed disks */ dm_descriptor_t *disks = dm_get_descriptors(DM_DRIVE, filter, &error); if (error) { handle_error("unable to communicate with libdiskmgt"); } else { int i; /* For each disk... */ for (i = 0; disks != NULL && disks[i] != NULL; i++) { dm_descriptor_t disk = (dm_descriptor_t)disks[i]; int online; /* Reset error flag for each disk */ error = 0; /* Is this disk online? */ online = get_disk_online(disk, &error); if (!error && online) { /* Get a dmgt_disk_t for this dm_descriptor_t */ dmgt_disk_t *dp = get_disk(disk, &error); if (!error) { /* * If this disk or any of its * slices is usable... */ if (!dp->in_use || zjni_count_elements( (void **)dp->slices) != 0) { /* Run the given function */ if (func(dp, data)) { error = -1; } dmgt_free_disk(dp); #ifdef DEBUG } else { (void) fprintf(stderr, "disk " "has no available slices: " "%s\n", dp->name); #endif } } } } dm_free_descriptors(disks); } return (error); }
void system_moniter(int interval){ get_mem(); get_disk(); get_cpu( interval ); }
static unsigned char *mfm_disk_get_track_ptr(mess_image *image, int track, int side) { struct mfm_disk_info *pDisk = get_disk(image); unsigned long TrackSize; TrackSize = mfm_disk_get_track_size(image); return (unsigned char *)((unsigned long)pDisk->pData + mfm_disk_header_size + (unsigned long)(TrackSize*((track*pDisk->NumSides)+side))); }
static void mfm_disk_read_sector_data_into_buffer(mess_image *image, int side, int index1, char *ptr, int length) { struct mfm_disk_info *mfm_disk = get_disk(image); unsigned char *pSectorPtr; mfm_disk_cache_data(image, mfm_disk->CurrentTrack, side); pSectorPtr = mfm_disk->sectors[index1].data_ptr+1; memcpy(ptr, pSectorPtr, length); }
/** * stheno_add_card - notify to insert card * * Return: 0 if successful, non 0 otherwise. */ int stheno_add_card( void ) { struct kobject *kobj = NULL; char env_major[32]; char *env[16]; int ret; int retval = -1; print_info( "stheno sdcard inserted.\n" ); if( stheno_gd == NULL ){ print_error( "stheno is not allocated.\n" ); goto exit; } /*stheno_read_sector0_flag = 1;*/ kobj = get_disk( stheno_gd ); if( kobj == NULL ) { print_error( "stheno get_disk failed.\n" ); goto exit; } snprintf( env_major, sizeof( env_major ), "MAJOR=%d", stheno_major ); env[0] = env_major; env[1] = "MINOR=0"; env[2] = "DEVNAME="STHENO_NAME; env[3] = "DEVTYPE=disk"; env[4] = "NPARTS=1"; env[5] = NULL; ret = kobject_uevent_env( kobj, KOBJ_ADD, env ); if( ret != 0 ){ print_error( "stheno 1st kobject_uevent(KOBJ_ADD) failed.(ret=%d)\n", ret ); /* ignore error because kobject_uevent_env() always returns -ENOENT(-2). */ /*goto exit;*/ } env[0] = env_major; env[1] = "MINOR=0"; env[2] = "DEVNAME="STHENO_NAME; env[3] = "DEVTYPE="; env[4] = "PARTN=1"; env[5] = NULL; ret = kobject_uevent_env( kobj, KOBJ_ADD, env ); if( ret != 0 ){ print_error( "stheno 2nd kobject_uevent(KOBJ_ADD) failed.(ret=%d)\n", ret ); /* ignore error because kobject_uevent_env() always returns -ENOENT(-2). */ /*goto exit;*/ } retval = 0; exit: if( kobj != NULL ) put_disk( stheno_gd ); return retval; }
static struct kobject * zvol_probe(dev_t dev, int *part, void *arg) { zvol_state_t *zv; struct kobject *kobj; mutex_enter(&zvol_state_lock); zv = zvol_find_by_dev(dev); kobj = zv ? get_disk(zv->zv_disk) : NULL; mutex_exit(&zvol_state_lock); return (kobj); }
static unsigned long mfm_disk_get_track_size(mess_image *image) { struct mfm_disk_info *pDisk = get_disk(image); switch (pDisk->Density) { case MFM_DISK_DENSITY_MFM_LO: return TrackSizeMFMLo; default: break; } return 0; }
// Go home and retrieve disk then move to center void load_disk(void) { if (digitalRead(ACTUATOR_LIMIT) == HIGH) // Check if a disk is already on the actuator { delay(50); // debounce if (digitalRead(ACTUATOR_LIMIT) == HIGH) { get_disk(); // No disk detected so we load one } } findCenter(); delay(500); place_disk(); }
static int mfm_disk_get_sectors_per_track(mess_image *image, int side) { struct mfm_disk_info *mfm_disk = get_disk(image); /* attempting to access an invalid side or track? */ if ((side>=mfm_disk->NumSides) || (mfm_disk->CurrentTrack>=mfm_disk->NumTracks)) { /* no sectors */ return 0; } mfm_disk_cache_data(image, mfm_disk->CurrentTrack, side); /* return number of sectors per track */ return mfm_disk->NumSectors; }
/* cache info about track */ static void mfm_disk_cache_data(mess_image *image, int track, int side) { struct mfm_disk_info *mfm_disk = get_disk(image); if ((track!=mfm_disk->CachedTrack) || (side!=mfm_disk->CachedSide)) { unsigned char *pTrackPtr = mfm_disk_get_track_ptr(image, track, side); unsigned long TrackSize = mfm_disk_get_track_size(image); mfm_info_cache_sector_info(image, pTrackPtr, TrackSize); mfm_disk->CachedTrack = track; mfm_disk->CachedSide = side; } }
void loop() { while (Serial.available()) // If serial data is available on the port { inByte = (char)Serial.read(); // Read a byte if (echo) Serial.print(inByte); // If the scho is on then print it back to the host if (inByte == '\r') // Once a /r is recvd check to see if it's a good command { if (echo) Serial.println(); // Dummy empty line if (inData == "up") lift_arm(); else if (inData == "downs") down_seek(50, 0); // Lower arm until it finds bottom else if (inData == "down") down(50, ARM_DN_POSITION); // Blindly lower arm else if (inData == "pump on") pump(ON); // Start pump else if (inData == "pump off") pump(OFF); // Stop pump else if (inData == "vent") pump_release(); // Stop pump and vent the vacuum else if (inData == "left") baseLeft(16); // Move base to the left else if (inData == "center") findCenter(); // Move base to the right else if (inData == "right") baseRight(BASE_CENTER_POSITION);// Move base to the right else if (inData == "stop") baseStop(); // Stop base else if (inData == "home") left_home(); // Mode base left until it finds home else if (inData == "status") stats(); // Show current status else if (inData == "stats") stats(); // Show current stats else if (inData == "get disk") get_disk(); // Macro to get disk and lift to top else if (inData == "load disk") load_disk(); // Macro to get disk and move to center else if (inData == "unload disk") unload_disk(); // Macro to get disk and move to center else if (inData == "place disk") place_disk(); // Macro to lower disk into tray else if (inData == "debug on") debug_mode = true; // turn on debug mode, prints encoder values else if (inData == "debug off") debug_mode = false; // Turn off debug mode else if (inData == "echo on") echo = true; // Turn on echo mode else if (inData == "echo off") echo = false; // Turn off echo mode else // The string wasn't recognized so it was a bad command { Serial.print("Error, Unknown Command: "); // Show the error Serial.println(inData); // Echo the command } inData = ""; // Clear the buffer (string) if (echo) prompt(); // reprint the prompt } else inData += inByte; // If it's not a /r then keep adding to the string (buffer) } }
static void mfm_disk_get_id_callback(mess_image *image, chrn_id *id, int id_index, int side) { struct mfm_disk_info *mfm_disk = get_disk(image); mfm_disk_cache_data(image, mfm_disk->CurrentTrack, side); if (id_index<mfm_disk->NumSectors) { /* construct a id value */ id->C = mfm_disk->sectors[id_index].id_ptr[1]; id->H = mfm_disk->sectors[id_index].id_ptr[2]; id->R = mfm_disk->sectors[id_index].id_ptr[3]; id->N = mfm_disk->sectors[id_index].id_ptr[4]; id->data_id = id_index; id->flags = 0; /* get dam - assumes double density - to be fixed */ if (mfm_disk->sectors[id_index].data_ptr[0]==0x0f8) { id->flags |= ID_FLAG_DELETED_DATA; } } }
void stheno_remove_card(void) { struct kobject* kobj; static char env_major[32]; char* env[16]; int i; seg_info.dirty = 0; if (!stheno_gd) return; kobj = get_disk(stheno_gd); if (!kobj) return; sprintf(env_major, "MAJOR=%d", stheno_major); i = 0; env[i++] = env_major; env[i++] = "MINOR=0"; env[i++] = "DEVNAME=stheno"; env[i++] = "DEVTYPE="; env[i++] = "PARTN=1"; env[i++] = NULL; kobject_uevent_env(kobj, KOBJ_REMOVE, env); #if 0 i = 0; env[i++] = env_major; env[i++] = "MINOR=0"; env[i++] = "DEVNAME=stheno"; env[i++] = "DEVTYPE=disk"; env[i++] = "NPARTS=1"; env[i++] = NULL; kobject_uevent_env(kobj, KOBJ_REMOVE, env); #endif put_disk(stheno_gd); }
u_char * var_diskio(struct variable * vp, oid * name, size_t * length, int exact, size_t * var_len, WriteMethod ** write_method) { /* * define any variables we might return as static! */ static long long_ret; static struct counter64 c64_ret; if (header_simple_table (vp, name, length, exact, var_len, write_method, MAX_DISKS)) return NULL; if (get_disk(name[*length - 1] - 1) == 0) return NULL; /* * We can now simply test on vp's magic number, defined in diskio.h */ switch (vp->magic) { case DISKIO_INDEX: long_ret = (long) name[*length - 1]; return (u_char *) & long_ret; case DISKIO_DEVICE: *var_len = strlen(ksp->ks_name); return (u_char *) ksp->ks_name; case DISKIO_NREAD: long_ret = (uint32_t) kio.nread; return (u_char *) & long_ret; case DISKIO_NWRITTEN: long_ret = (uint32_t) kio.nwritten; return (u_char *) & long_ret; case DISKIO_NREADX: *var_len = sizeof(struct counter64); c64_ret.low = kio.nread & 0xffffffff;; c64_ret.high = kio.nread >> 32; return (u_char *) & c64_ret; case DISKIO_NWRITTENX: *var_len = sizeof(struct counter64); c64_ret.low = kio.nwritten & 0xffffffff;; c64_ret.high = kio.nwritten >> 32; return (u_char *) & c64_ret; case DISKIO_READS: long_ret = (uint32_t) kio.reads; return (u_char *) & long_ret; case DISKIO_WRITES: long_ret = (uint32_t) kio.writes; return (u_char *) & long_ret; default: ERROR_MSG("diskio.c: don't know how to handle this request."); } /* * if we fall to here, fail by returning NULL */ return NULL; }
int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data) { FATFS *fat; FRESULT result; int index; struct rt_device_blk_geometry geometry; /* get an empty position */ index = get_disk(RT_NULL); if (index == -1) return -DFS_STATUS_ENOENT; /* save device */ disk[index] = fs->dev_id; /* check sector size */ if (rt_device_control(fs->dev_id, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry) == RT_EOK) { if (geometry.bytes_per_sector > _MAX_SS) { rt_kprintf("The sector size of device is greater than the sector size of FAT.\n"); return -DFS_STATUS_EINVAL; } } fat = (FATFS *)rt_malloc(sizeof(FATFS)); if (fat == RT_NULL) { disk[index] = RT_NULL; return -DFS_STATUS_ENOMEM; } /* mount fatfs, always 0 logic driver */ result = f_mount(fat,"", (BYTE)index); if (result == FR_OK) { char drive[8]; DIR *dir; rt_snprintf(drive, sizeof(drive), "%d:/", index); dir = (DIR *)rt_malloc(sizeof(DIR)); if (dir == RT_NULL) { f_mount(RT_NULL,"",(BYTE)index); disk[index] = RT_NULL; rt_free(fat); return -DFS_STATUS_ENOMEM; } /* open the root directory to test whether the fatfs is valid */ result = f_opendir(dir, drive); if (result != FR_OK) goto __err; /* mount succeed! */ fs->data = fat; rt_free(dir); return 0; } __err: f_mount(RT_NULL, "", (BYTE)index); disk[index] = RT_NULL; rt_free(fat); return elm_result_to_dfs(result); }
/* ins_disk */ WORD ins_disk(ANODE *pa) { LONG tree; WORD change, icon, flop, hard, fld; BYTE cletter[2], clabel[13]; BYTE nletter[2], nlabel[13]; ANODE *newpa; tree = G.a_trees[ADINSDIS]; change = FALSE; cletter[0] = pa->a_letter; cletter[1] = '\0'; strcpy(&clabel[0], pa->a_pappl); inf_sset(tree, DRID, &cletter[0]); inf_sset(tree, DRLABEL, &clabel[0]); flop = (pa->a_aicon == IG_FLOPPY) ? SELECTED : NORMAL; hard = (pa->a_aicon == IG_HARD) ? SELECTED : NORMAL; LWSET(OB_STATE(DRFLOPPY), flop); LWSET(OB_STATE(DRHARD), hard); LWSET(OB_STATE(DRREM), (lastdisk()) ? DISABLED : NORMAL ); inf_show(tree, 0); inf_sget(tree, DRID, &nletter[0]); inf_sget(tree, DRLABEL, &nlabel[0]); fld = inf_gindex(tree, DRINST, 3); /* which exit button? */ LWSET(OB_STATE(DRINST + fld), NORMAL); icon = ( LWGET(OB_STATE(DRFLOPPY)) & SELECTED ); icon = (icon) ? IG_FLOPPY : IG_HARD; if ( fld == 0 ) /* Install */ { if ( (cletter[0] != nletter[0]) && (nletter[0] != '\0') ) { newpa = get_disk(nletter[0]); if (!newpa) { newpa = app_alloc(FALSE); if (newpa) { newpa->a_flags = pa->a_flags; newpa->a_type = pa->a_type; newpa->a_obid = pa->a_obid; newpa->a_pappl = pa->a_pappl; scan_str("@", &newpa->a_pdata); newpa->a_aicon = pa->a_aicon; newpa->a_dicon = NIL; newpa->a_letter = nletter[0]; } /* if newpa */ else fun_alert(1, STAPGONE, NULL); } /* if !newpa */ if (newpa) pa = newpa; change = TRUE; } /* if cletter */ /* see if icon changed */ if (pa->a_aicon != icon) { pa->a_aicon = icon; change = TRUE; } /* see if label changed */ if ( (!strcmp(&clabel[0], &nlabel[0])) && (nlabel[0] != '\0') ) { nlabel[ strlen(&nlabel[0]) ] = '@'; scan_str(&nlabel[0], &pa->a_pappl); change = TRUE; } } /* if INSTALL */ else if ( fld == 1 ) /* Remove */ { /* find matching anode delete it */ for (pa = G.g_ahead; pa; pa = pa->a_next) { if ( (pa->a_aicon == icon) && (pa->a_letter == nletter[0]) ) { app_free(pa); change = TRUE; } } /* for */ } /* if REMOVE */ return(change); } /* ins_disk */
int dfs_elm_mkfs(rt_device_t dev_id) { #define FSM_STATUS_INIT 0 #define FSM_STATUS_USE_TEMP_DRIVER 1 FATFS *fat = RT_NULL; BYTE *work; int flag; FRESULT result; int index; work = rt_malloc(_MAX_SS); if(RT_NULL == work) { return -DFS_STATUS_ENOMEM; } if (dev_id == RT_NULL) return -DFS_STATUS_EINVAL; /* if the device is already mounted, then just do mkfs to the drv, * while if it is not mounted yet, then find an empty drive to do mkfs */ flag = FSM_STATUS_INIT; index = get_disk(dev_id); if (index == -1) { /* not found the device id */ index = get_disk(RT_NULL); if (index == -1) { /* no space to store an temp driver */ rt_kprintf("sorry, there is no space to do mkfs! \n"); return -DFS_STATUS_ENOSPC; } else { fat = rt_malloc(sizeof(FATFS)); if (fat == RT_NULL) return -DFS_STATUS_ENOMEM; flag = FSM_STATUS_USE_TEMP_DRIVER; disk[index] = dev_id; /* try to open device */ rt_device_open(dev_id, RT_DEVICE_OFLAG_RDWR); /* just fill the FatFs[vol] in ff.c, or mkfs will failded! * consider this condition: you just umount the elm fat, * then the space in FatFs[index] is released, and now do mkfs * on the disk, you will get a failure. so we need f_mount here, * just fill the FatFS[index] in elm fatfs to make mkfs work. */ f_mount(fat, "", (BYTE)index); } } /* [IN] Logical drive number */ /* [IN] Format options */ /* [IN] Size of the allocation unit */ /* [-] Working buffer */ /* [IN] Size of working buffer */ result = f_mkfs("", FM_ANY, 0, work, _MAX_SS); rt_free(work); /* check flag status, we need clear the temp driver stored in disk[] */ if (flag == FSM_STATUS_USE_TEMP_DRIVER) { rt_free(fat); f_mount(RT_NULL, "",(BYTE)index); disk[index] = RT_NULL; /* close device */ rt_device_close(dev_id); } if (result != FR_OK) { rt_kprintf("format error\n"); return elm_result_to_dfs(result); } return DFS_STATUS_OK; }
/* Create disk on demand. So we won't create lots of disk for un-used devices. */ static struct kobject *tzmem_blk_probe(dev_t dev, int *part, void *data) { uint32_t len; struct gendisk *disk; struct kobject *kobj; struct request_queue *queue; struct tzmem_diskinfo_s *diskInfo; int ret; KREE_SESSION_HANDLE session; #ifdef MTEE_TZMEM_DBG pr_warn("====> tzmem_blk_probe\n"); #endif mutex_lock(&tzmem_probe_mutex); diskInfo = (struct tzmem_diskinfo_s *) &_tzmem_diskInfo[tzmem_poolIndex]; if (diskInfo->disk == NULL) { disk = alloc_disk(1); if (!disk) goto out_info; queue = blk_init_queue(do_tzmem_blk_request, &tzmem_blk_lock); if (!queue) goto out_queue; blk_queue_max_hw_sectors(queue, 1024); blk_queue_bounce_limit(queue, BLK_BOUNCE_ANY); if (_tzmem_get_poolsize(&len)) goto out_init; disk->major = IO_NODE_MAJOR_TZMEM; disk->first_minor = MINOR(dev); disk->fops = &tzmem_blk_fops; disk->private_data = &_tzmem_diskInfo; snprintf(disk->disk_name, sizeof(disk->disk_name), "tzmem%d", MINOR(dev)); disk->queue = queue; set_capacity(disk, len / 512); add_disk(disk); ret = KREE_CreateSession(TZ_TA_MEM_UUID, &session); if (ret != TZ_RESULT_SUCCESS) { pr_debug(MTEE_TZMEM_TAG "[%s] _tzmem_get_poolsize: KREE_CreateSession Error = 0x%x\n", MODULE_NAME, ret); goto out_init; } diskInfo->session = session; diskInfo->pool_size = len; diskInfo->disk = disk; diskInfo->size = len; } *part = 0; kobj = diskInfo ? get_disk(diskInfo->disk) : ERR_PTR(-ENOMEM); mutex_unlock(&tzmem_probe_mutex); return kobj; out_init: blk_cleanup_queue(queue); out_queue: put_disk(disk); out_info: mutex_unlock(&tzmem_probe_mutex); return ERR_PTR(-ENOMEM); }
static void accept_request(void* data) { char recvbuf[MAXLINE]; char tmpbuf[43]; int mem_total, disk_all, disk_use; int type, keytype; int clientfd = (int)(long)data; pr_peeraddr(clientfd); for (;;) { int flag = anet_tcp_readline(clientfd, recvbuf, sizeof(recvbuf), 0); if (flag == -1) { ERROR_NO("readline error!"); return; } else if (flag == 0) { DEBUG("peer close!\n"); return; } DEBUG("%s", recvbuf); switch(recvbuf[0]) { case 'S': if (isboot == 1) { anet_tcp_send(clientfd, FAIL, strlen(FAIL), 0); break; } flag = server_start(); if (flag == -1) { anet_tcp_send(clientfd, FAIL, strlen(FAIL), 0); INFO("Service start fail!"); break; } server_run(); isboot = 1; anet_tcp_send(clientfd, OK, strlen(OK), 0); INFO("Service start!"); break; case 'E': if (isboot == 0) { anet_tcp_send(clientfd, FAIL, strlen(FAIL), 0); INFO("Service stop fail!"); break; } server_stop(); isboot = 0; anet_tcp_send(clientfd, OK, strlen(OK), 0); INFO("Service stop!"); break; case 'A': if (isboot == 1) { type = recvbuf[1] - '0'; keytype = recvbuf[2] - '0'; match_rebuild(type, keytype); anet_tcp_send(clientfd, OK, strlen(OK), 0); break; } anet_tcp_send(clientfd, FAIL, strlen(FAIL), 0); break; case 'D': if (isboot == 1) { type = recvbuf[1] - '0'; keytype = recvbuf[2] - '0'; match_rebuild(type, keytype); anet_tcp_send(clientfd, OK, strlen(OK), 0); break; } anet_tcp_send(clientfd, FAIL, strlen(FAIL), 0); break; case 'C': sprintf(tmpbuf, "%lf\n", get_cpu()); anet_tcp_send(clientfd, tmpbuf, strlen(tmpbuf), 0); break; case 'H': sprintf(tmpbuf, "%lf\n", get_disk(&disk_all, &disk_use)); anet_tcp_send(clientfd, tmpbuf, strlen(tmpbuf), 0); break; case 'M': sprintf(tmpbuf, "%lf\n", get_mem(&mem_total)); anet_tcp_send(clientfd, tmpbuf, strlen(tmpbuf), 0); break; default: anet_tcp_send(clientfd, FAIL, strlen(FAIL), 0); } } close(clientfd); }
static void mfm_disk_seek_callback(mess_image *image, int physical_track) { struct mfm_disk_info *mfm_disk = get_disk(image); mfm_disk->CurrentTrack = physical_track; }
int do_proc_diskstats(int update_every, unsigned long long dt) { static procfile *ff = NULL; static char path_to_get_hw_sector_size[FILENAME_MAX + 1] = ""; static int enable_new_disks = -1; static int do_io = -1, do_ops = -1, do_mops = -1, do_iotime = -1, do_qops = -1, do_util = -1, do_backlog = -1; if(enable_new_disks == -1) enable_new_disks = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "enable new disks detected at runtime", CONFIG_ONDEMAND_ONDEMAND); if(do_io == -1) do_io = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "bandwidth for all disks", CONFIG_ONDEMAND_ONDEMAND); if(do_ops == -1) do_ops = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "operations for all disks", CONFIG_ONDEMAND_ONDEMAND); if(do_mops == -1) do_mops = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "merged operations for all disks", CONFIG_ONDEMAND_ONDEMAND); if(do_iotime == -1) do_iotime = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "i/o time for all disks", CONFIG_ONDEMAND_ONDEMAND); if(do_qops == -1) do_qops = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "queued operations for all disks", CONFIG_ONDEMAND_ONDEMAND); if(do_util == -1) do_util = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "utilization percentage for all disks", CONFIG_ONDEMAND_ONDEMAND); if(do_backlog == -1)do_backlog = config_get_boolean_ondemand("plugin:proc:/proc/diskstats", "backlog for all disks", CONFIG_ONDEMAND_ONDEMAND); if(!ff) { char filename[FILENAME_MAX + 1]; snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/proc/diskstats"); ff = procfile_open(config_get("plugin:proc:/proc/diskstats", "filename to monitor", filename), " \t", PROCFILE_FLAG_DEFAULT); } if(!ff) return 1; if(!path_to_get_hw_sector_size[0]) { char filename[FILENAME_MAX + 1]; snprintfz(filename, FILENAME_MAX, "%s%s", global_host_prefix, "/sys/block/%s/queue/hw_sector_size"); snprintfz(path_to_get_hw_sector_size, FILENAME_MAX, "%s", config_get("plugin:proc:/proc/diskstats", "path to get h/w sector size", filename)); } ff = procfile_readall(ff); if(!ff) return 0; // we return 0, so that we will retry to open it next time uint32_t lines = procfile_lines(ff), l; uint32_t words; for(l = 0; l < lines ;l++) { char *disk; unsigned long long major = 0, minor = 0, reads = 0, mreads = 0, readsectors = 0, readms = 0, writes = 0, mwrites = 0, writesectors = 0, writems = 0, queued_ios = 0, busy_ms = 0, backlog_ms = 0; unsigned long long last_reads = 0, last_readsectors = 0, last_readms = 0, last_writes = 0, last_writesectors = 0, last_writems = 0, last_busy_ms = 0; words = procfile_linewords(ff, l); if(words < 14) continue; major = strtoull(procfile_lineword(ff, l, 0), NULL, 10); minor = strtoull(procfile_lineword(ff, l, 1), NULL, 10); disk = procfile_lineword(ff, l, 2); // # of reads completed # of writes completed // This is the total number of reads or writes completed successfully. reads = strtoull(procfile_lineword(ff, l, 3), NULL, 10); // rd_ios writes = strtoull(procfile_lineword(ff, l, 7), NULL, 10); // wr_ios // # of reads merged # of writes merged // Reads and writes which are adjacent to each other may be merged for // efficiency. Thus two 4K reads may become one 8K read before it is // ultimately handed to the disk, and so it will be counted (and queued) mreads = strtoull(procfile_lineword(ff, l, 4), NULL, 10); // rd_merges_or_rd_sec mwrites = strtoull(procfile_lineword(ff, l, 8), NULL, 10); // wr_merges // # of sectors read # of sectors written // This is the total number of sectors read or written successfully. readsectors = strtoull(procfile_lineword(ff, l, 5), NULL, 10); // rd_sec_or_wr_ios writesectors = strtoull(procfile_lineword(ff, l, 9), NULL, 10); // wr_sec // # of milliseconds spent reading # of milliseconds spent writing // This is the total number of milliseconds spent by all reads or writes (as // measured from __make_request() to end_that_request_last()). readms = strtoull(procfile_lineword(ff, l, 6), NULL, 10); // rd_ticks_or_wr_sec writems = strtoull(procfile_lineword(ff, l, 10), NULL, 10); // wr_ticks // # of I/Os currently in progress // The only field that should go to zero. Incremented as requests are // given to appropriate struct request_queue and decremented as they finish. queued_ios = strtoull(procfile_lineword(ff, l, 11), NULL, 10); // ios_pgr // # of milliseconds spent doing I/Os // This field increases so long as field queued_ios is nonzero. busy_ms = strtoull(procfile_lineword(ff, l, 12), NULL, 10); // tot_ticks // weighted # of milliseconds spent doing I/Os // This field is incremented at each I/O start, I/O completion, I/O // merge, or read of these stats by the number of I/Os in progress // (field queued_ios) times the number of milliseconds spent doing I/O since the // last update of this field. This can provide an easy measure of both // I/O completion time and the backlog that may be accumulating. backlog_ms = strtoull(procfile_lineword(ff, l, 13), NULL, 10); // rq_ticks int def_enabled = 0; // remove slashes from disk names char *s; for(s = disk; *s ;s++) if(*s == '/') *s = '_'; struct disk *d = get_disk(major, minor); if(d->partition_id == -1) def_enabled = enable_new_disks; else def_enabled = 0; char *family = d->family; if(!family) family = disk; /* switch(major) { case 9: // MDs case 43: // network block case 144: // nfs case 145: // nfs case 146: // nfs case 199: // veritas case 201: // veritas case 251: // dm case 253: // virtio def_enabled = enable_new_disks; break; case 48: // RAID case 49: // RAID case 50: // RAID case 51: // RAID case 52: // RAID case 53: // RAID case 54: // RAID case 55: // RAID case 112: // RAID case 136: // RAID case 137: // RAID case 138: // RAID case 139: // RAID case 140: // RAID case 141: // RAID case 142: // RAID case 143: // RAID case 179: // MMC case 180: // USB if(minor % 8) def_enabled = 0; // partitions else def_enabled = enable_new_disks; break; case 8: // scsi disks case 65: // scsi disks case 66: // scsi disks case 67: // scsi disks case 68: // scsi disks case 69: // scsi disks case 70: // scsi disks case 71: // scsi disks case 72: // scsi disks case 73: // scsi disks case 74: // scsi disks case 75: // scsi disks case 76: // scsi disks case 77: // scsi disks case 78: // scsi disks case 79: // scsi disks case 80: // i2o case 81: // i2o case 82: // i2o case 83: // i2o case 84: // i2o case 85: // i2o case 86: // i2o case 87: // i2o case 101: // hyperdisk case 102: // compressed case 104: // scsi case 105: // scsi case 106: // scsi case 107: // scsi case 108: // scsi case 109: // scsi case 110: // scsi case 111: // scsi case 114: // bios raid case 116: // ram board case 128: // scsi case 129: // scsi case 130: // scsi case 131: // scsi case 132: // scsi case 133: // scsi case 134: // scsi case 135: // scsi case 153: // raid case 202: // xen case 254: // virtio3 case 256: // flash case 257: // flash case 259: // nvme0n1 issue #119 if(minor % 16) def_enabled = 0; // partitions else def_enabled = enable_new_disks; break; case 160: // raid case 161: // raid if(minor % 32) def_enabled = 0; // partitions else def_enabled = enable_new_disks; break; case 3: // ide case 13: // 8bit ide case 22: // ide case 33: // ide case 34: // ide case 56: // ide case 57: // ide case 88: // ide case 89: // ide case 90: // ide case 91: // ide if(minor % 64) def_enabled = 0; // partitions else def_enabled = enable_new_disks; break; case 252: // zram def_enabled = 0; break; default: def_enabled = 0; break; } */ int ddo_io = do_io, ddo_ops = do_ops, ddo_mops = do_mops, ddo_iotime = do_iotime, ddo_qops = do_qops, ddo_util = do_util, ddo_backlog = do_backlog; // check which charts are enabled for this disk { char var_name[4096 + 1]; snprintfz(var_name, 4096, "plugin:proc:/proc/diskstats:%s", disk); def_enabled = config_get_boolean_ondemand(var_name, "enabled", def_enabled); if(def_enabled == CONFIG_ONDEMAND_NO) continue; if(def_enabled == CONFIG_ONDEMAND_ONDEMAND && !reads && !writes) continue; ddo_io = config_get_boolean_ondemand(var_name, "bandwidth", ddo_io); ddo_ops = config_get_boolean_ondemand(var_name, "operations", ddo_ops); ddo_mops = config_get_boolean_ondemand(var_name, "merged operations", ddo_mops); ddo_iotime = config_get_boolean_ondemand(var_name, "i/o time", ddo_iotime); ddo_qops = config_get_boolean_ondemand(var_name, "queued operations", ddo_qops); ddo_util = config_get_boolean_ondemand(var_name, "utilization percentage", ddo_util); ddo_backlog = config_get_boolean_ondemand(var_name, "backlog", ddo_backlog); // by default, do not add charts that do not have values if(ddo_io == CONFIG_ONDEMAND_ONDEMAND && !reads && !writes) ddo_io = 0; if(ddo_mops == CONFIG_ONDEMAND_ONDEMAND && mreads == 0 && mwrites == 0) ddo_mops = 0; if(ddo_iotime == CONFIG_ONDEMAND_ONDEMAND && readms == 0 && writems == 0) ddo_iotime = 0; if(ddo_util == CONFIG_ONDEMAND_ONDEMAND && busy_ms == 0) ddo_util = 0; if(ddo_backlog == CONFIG_ONDEMAND_ONDEMAND && backlog_ms == 0) ddo_backlog = 0; if(ddo_qops == CONFIG_ONDEMAND_ONDEMAND && backlog_ms == 0) ddo_qops = 0; // for absolute values, we need to switch the setting to 'yes' // to allow it refresh from now on if(ddo_qops == CONFIG_ONDEMAND_ONDEMAND) config_set(var_name, "queued operations", "yes"); } RRDSET *st; // -------------------------------------------------------------------- int sector_size = 512; if(ddo_io) { st = rrdset_find_bytype(RRD_TYPE_DISK, disk); if(!st) { char tf[FILENAME_MAX + 1], *t; char ssfilename[FILENAME_MAX + 1]; strncpyz(tf, disk, FILENAME_MAX); // replace all / with ! while((t = strchr(tf, '/'))) *t = '!'; snprintfz(ssfilename, FILENAME_MAX, path_to_get_hw_sector_size, tf); FILE *fpss = fopen(ssfilename, "r"); if(fpss) { char ssbuffer[1025]; char *tmp = fgets(ssbuffer, 1024, fpss); if(tmp) { sector_size = atoi(tmp); if(sector_size <= 0) { error("Invalid sector size %d for device %s in %s. Assuming 512.", sector_size, disk, ssfilename); sector_size = 512; } } else error("Cannot read data for sector size for device %s from %s. Assuming 512.", disk, ssfilename); fclose(fpss); } else error("Cannot read sector size for device %s from %s. Assuming 512.", disk, ssfilename); st = rrdset_create(RRD_TYPE_DISK, disk, NULL, family, "disk.io", "Disk I/O Bandwidth", "kilobytes/s", 2000, update_every, RRDSET_TYPE_AREA); rrddim_add(st, "reads", NULL, sector_size, 1024, RRDDIM_INCREMENTAL); rrddim_add(st, "writes", NULL, sector_size * -1, 1024, RRDDIM_INCREMENTAL); } else rrdset_next_usec(st, dt); last_readsectors = rrddim_set(st, "reads", readsectors); last_writesectors = rrddim_set(st, "writes", writesectors); rrdset_done(st); } // -------------------------------------------------------------------- if(ddo_ops) { st = rrdset_find_bytype("disk_ops", disk); if(!st) { st = rrdset_create("disk_ops", disk, NULL, family, "disk.ops", "Disk Completed I/O Operations", "operations/s", 2001, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next_usec(st, dt); last_reads = rrddim_set(st, "reads", reads); last_writes = rrddim_set(st, "writes", writes); rrdset_done(st); } // -------------------------------------------------------------------- if(ddo_qops) { st = rrdset_find_bytype("disk_qops", disk); if(!st) { st = rrdset_create("disk_qops", disk, NULL, family, "disk.qops", "Disk Current I/O Operations", "operations", 2002, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "operations", NULL, 1, 1, RRDDIM_ABSOLUTE); } else rrdset_next_usec(st, dt); rrddim_set(st, "operations", queued_ios); rrdset_done(st); } // -------------------------------------------------------------------- if(ddo_backlog) { st = rrdset_find_bytype("disk_backlog", disk); if(!st) { st = rrdset_create("disk_backlog", disk, NULL, family, "disk.backlog", "Disk Backlog", "backlog (ms)", 2003, update_every, RRDSET_TYPE_AREA); st->isdetail = 1; rrddim_add(st, "backlog", NULL, 1, 10, RRDDIM_INCREMENTAL); } else rrdset_next_usec(st, dt); rrddim_set(st, "backlog", backlog_ms); rrdset_done(st); } // -------------------------------------------------------------------- if(ddo_util) { st = rrdset_find_bytype("disk_util", disk); if(!st) { st = rrdset_create("disk_util", disk, NULL, family, "disk.util", "Disk Utilization Time", "% of time working", 2004, update_every, RRDSET_TYPE_AREA); st->isdetail = 1; rrddim_add(st, "utilization", NULL, 1, 10, RRDDIM_INCREMENTAL); } else rrdset_next_usec(st, dt); last_busy_ms = rrddim_set(st, "utilization", busy_ms); rrdset_done(st); } // -------------------------------------------------------------------- if(ddo_mops) { st = rrdset_find_bytype("disk_mops", disk); if(!st) { st = rrdset_create("disk_mops", disk, NULL, family, "disk.mops", "Disk Merged Operations", "merged operations/s", 2021, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next_usec(st, dt); rrddim_set(st, "reads", mreads); rrddim_set(st, "writes", mwrites); rrdset_done(st); } // -------------------------------------------------------------------- if(ddo_iotime) { st = rrdset_find_bytype("disk_iotime", disk); if(!st) { st = rrdset_create("disk_iotime", disk, NULL, family, "disk.iotime", "Disk Total I/O Time", "milliseconds/s", 2022, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_INCREMENTAL); rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_INCREMENTAL); } else rrdset_next_usec(st, dt); last_readms = rrddim_set(st, "reads", readms); last_writems = rrddim_set(st, "writes", writems); rrdset_done(st); } // -------------------------------------------------------------------- // calculate differential charts // only if this is not the first time we run if(dt) { if(ddo_iotime && ddo_ops) { st = rrdset_find_bytype("disk_await", disk); if(!st) { st = rrdset_create("disk_await", disk, NULL, family, "disk.await", "Average Completed I/O Operation Time", "ms per operation", 2005, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "reads", NULL, 1, 1, RRDDIM_ABSOLUTE); rrddim_add(st, "writes", NULL, -1, 1, RRDDIM_ABSOLUTE); } else rrdset_next_usec(st, dt); rrddim_set(st, "reads", (reads - last_reads) ? (readms - last_readms) / (reads - last_reads) : 0); rrddim_set(st, "writes", (writes - last_writes) ? (writems - last_writems) / (writes - last_writes) : 0); rrdset_done(st); } if(ddo_io && ddo_ops) { st = rrdset_find_bytype("disk_avgsz", disk); if(!st) { st = rrdset_create("disk_avgsz", disk, NULL, family, "disk.avgsz", "Average Completed I/O Operation Bandwidth", "kilobytes per operation", 2006, update_every, RRDSET_TYPE_AREA); st->isdetail = 1; rrddim_add(st, "reads", NULL, sector_size, 1024, RRDDIM_ABSOLUTE); rrddim_add(st, "writes", NULL, -sector_size, 1024, RRDDIM_ABSOLUTE); } else rrdset_next_usec(st, dt); rrddim_set(st, "reads", (reads - last_reads) ? (readsectors - last_readsectors) / (reads - last_reads) : 0); rrddim_set(st, "writes", (writes - last_writes) ? (writesectors - last_writesectors) / (writes - last_writes) : 0); rrdset_done(st); } if(ddo_util && ddo_ops) { st = rrdset_find_bytype("disk_svctm", disk); if(!st) { st = rrdset_create("disk_svctm", disk, NULL, family, "disk.svctm", "Average Service Time", "ms per operation", 2007, update_every, RRDSET_TYPE_LINE); st->isdetail = 1; rrddim_add(st, "svctm", NULL, 1, 1, RRDDIM_ABSOLUTE); } else rrdset_next_usec(st, dt); rrddim_set(st, "svctm", ((reads - last_reads) + (writes - last_writes)) ? (busy_ms - last_busy_ms) / ((reads - last_reads) + (writes - last_writes)) : 0); rrdset_done(st); } } } return 0; }
/* TODO: Error checking if a id is found at very end of track, or a sector which goes over end of track */ static void mfm_info_cache_sector_info(mess_image *image,unsigned char *pTrackPtr, unsigned long Length) { /* initialise these with single density values if single density */ unsigned char IdMark = 0x0fe; unsigned char DataMark = 0x0fb; unsigned char DeletedDataMark = 0x0f8; unsigned long SectorCount; unsigned long N = 0; unsigned long SearchCode = 0; unsigned char *pStart = pTrackPtr; struct mfm_disk_info *mfm_disk = get_disk(image); SectorCount = 0; do { switch (SearchCode) { /* searching for id's */ case 0: { /* found id mark? */ if (pTrackPtr[0] == IdMark) { /* store pointer to id mark */ mfm_disk->sectors[SectorCount].id_ptr = pTrackPtr; SectorCount++; /* grab N value - used to skip data in data field */ N = pTrackPtr[4]; /* skip past id field and crc */ pTrackPtr+=7; /* now looking for data field */ SearchCode = 1; } else { /* update position */ pTrackPtr++; } } break; /* searching for data id's */ case 1: { /* found data or deleted data? */ if ((pTrackPtr[0] == DataMark) || (pTrackPtr[0] == DeletedDataMark)) { /* yes */ mfm_disk->sectors[SectorCount-1].data_ptr = pTrackPtr; /* skip data field and id */ pTrackPtr+=(1<<(N+7)) + 3; /* now looking for id field */ SearchCode = 0; } else { pTrackPtr++; } } break; default: break; } } while ((pTrackPtr-pStart)<Length); mfm_disk->NumSectors = SectorCount; logerror("mfm disk: Num Sectors %02x\n,", (int) SectorCount); }