static uint64_t __disk_size(const char *path) { int fd; uint64_t size; fd = os_disk_open_raw(path, OS_DISK_READ); UT_ASSERT(fd >= 0); UT_ASSERT_EQUAL(0, os_disk_get_size(fd, &size)); close(fd); return size; }
int __file_stream_on(stream_t **stream, FILE *file, stream_access_t access, bool close_all) { file_stream_context_t *fsc; struct stat stat; int err; if (fstat(fileno(file), &stat) < 0) return -errno; fsc = os_malloc(sizeof(file_stream_context_t)); if (fsc == NULL) return -ENOMEM; fsc->file = file; fsc->close_all = close_all; fsc->is_bdev = S_ISBLK(stat.st_mode) ? true : false; if (fsc->is_bdev) { int err = os_disk_get_size(fileno(file), &fsc->bdev_size); if (err != 0) { os_free(fsc); return err; } } else fsc->bdev_size = 0; err = stream_open(stream, fsc, &file_stream_ops, access); if (err != 0) { os_free(fsc); return err; } return 0; }
static int do_io(const char *disk_path, bool async, bool write, uint64_t offset, uint64_t size_in_bytes) { int exa_rdev_fd; int disk_fd; exa_rdev_handle_t *dev_req; uint64_t disk_size; int ret; /* Get disk size */ disk_fd = os_disk_open_raw(disk_path, OS_DISK_READ); if (disk_fd < 0) { fprintf(stderr, "Can not open disk %s\n", disk_path); return -1; } ret = os_disk_get_size(disk_fd, &disk_size); if (ret < 0) { fprintf(stderr, "Can not get the size of disk %s\n", disk_path); return -1; } fprintf(stderr, "Disk %s has a size of %"PRIu64" bytes\n", disk_path, disk_size); /* Initialise exa_rdev */ exa_rdev_fd = exa_rdev_init(); if (exa_rdev_fd <= 0) { fprintf(stderr, "exa_rdev_init() failed\n"); return -1; } dev_req = exa_rdev_handle_alloc(disk_path); if (dev_req == NULL) { fprintf(stderr, "exa_rdev_request_init() failed, disk_path = %s\n", disk_path); close(exa_rdev_fd); return -1; } /* Carry on requests to exa_rdev */ if (async) { fprintf(stderr, "Asynchronous mode\n"); if (write) async_op(RDEV_OP_WRITE, offset, size_in_bytes, dev_req); else async_op(RDEV_OP_READ, offset, size_in_bytes, dev_req); } else { fprintf(stderr, "Synchronous mode\n"); if (write) sync_op(RDEV_OP_WRITE, offset, size_in_bytes, dev_req); else sync_op(RDEV_OP_READ, offset, size_in_bytes, dev_req); } fprintf(stderr, "Finished %s %"PRIu64 " bytes on disk %s at offset %"PRIu64 "\n", (write == true) ? "writing" : "reading", size_in_bytes, disk_path, offset); close(exa_rdev_fd); return 0; }
void rebuild_helper_thread(void *p) { ExamsgHandle mh; int err; exalog_as(EXAMSG_NBD_SERVER_ID); /* initialize examsg framework */ mh = examsgInit(EXAMSG_NBD_LOCKING_ID); EXA_ASSERT(mh != NULL); err = examsgAddMbox(mh, EXAMSG_NBD_LOCKING_ID, 1, 5 * EXAMSG_MSG_MAX); EXA_ASSERT(err == 0); os_sem_post(&nbd_server.mailbox_sem); while (nbd_server.run) { device_t *device; ExamsgNbdLock nbd_lock_msg; ExamsgMID from; struct timeval timeout = { .tv_sec = 0, .tv_usec = 100000 }; exa_nodeset_t dest_nodes; err = examsgWaitTimeout(mh, &timeout); /* Just in order to check stopping the thread is required*/ if (err == -ETIME) continue; if (err != 0) { exalog_error("Locking thread encountered error %s (%d) while " "waiting in event loop.", exa_error_msg(err), err); continue; } err = examsgRecv(mh, &from, &nbd_lock_msg, sizeof(nbd_lock_msg)); /* No message */ if (err == 0) continue; if (err < 0) { exalog_error("Locking thread encountered error %s (%d) while " "receiving a messsage.", exa_error_msg(err), err); continue; } switch(nbd_lock_msg.any.type) { case EXAMSG_NBD_LOCK: /* find device from name */ /* FIXME devices lock is not held... it should */ device = find_device_from_uuid(&nbd_lock_msg.disk_uuid); if (device == NULL) { exalog_error("Unknown device with UUID " UUID_FMT, UUID_VAL(&nbd_lock_msg.disk_uuid)); err = -CMD_EXP_ERR_UNKNOWN_DEVICE; break; } if (nbd_lock_msg.lock) { err = exa_disk_lock_zone(device, nbd_lock_msg.locked_zone_start, nbd_lock_msg.locked_zone_size); EXA_ASSERT_VERBOSE(err == 0, "Trying to lock too many zone " "(>%d). Last zone not succesfully locked " "(start = %" PRId64 ", size = %" PRId64 " ) " "on device UUID " UUID_FMT, NBMAX_DISK_LOCKED_ZONES, nbd_lock_msg.locked_zone_start, nbd_lock_msg.locked_zone_size, UUID_VAL(&nbd_lock_msg.disk_uuid)); } else { err = exa_disk_unlock_zone(device, nbd_lock_msg.locked_zone_start, nbd_lock_msg.locked_zone_size); EXA_ASSERT_VERBOSE(err == 0, "Trying to unlock a never locked " "zone (unlocked zone start =%" PRId64 ", " "unlocked zone size = %" PRId64 ") on device" " UUID " UUID_FMT, nbd_lock_msg.locked_zone_start, nbd_lock_msg.locked_zone_size, UUID_VAL(&nbd_lock_msg.disk_uuid)); } break; default: /* error */ EXA_ASSERT_VERBOSE(false, "Locking thread got unknown message of" " type %d ", nbd_lock_msg.any.type); break; } exa_nodeset_single(&dest_nodes, from.netid.node); examsgAckReply(mh, (Examsg *)&nbd_lock_msg, err, from.id, &dest_nodes); } examsgDelMbox(mh, EXAMSG_NBD_LOCKING_ID); examsgExit(mh); } /** get the number of sector of the device * \param device_path the device to get the number of sector * \param nb_sectors64 the number of sectors of the device * \return nb_sectors the returned number of sector */ static int get_nb_sectors(const char *device_path, uint64_t *nb_sectors) { uint64_t device_size; /* in bytes */ int retval; int fd; /* We need the read access to get the size. */ if ((fd = os_disk_open_raw(device_path, OS_DISK_READ)) < 0) { exalog_error("cannot open device '%s' error=%s ", device_path, exa_error_msg(-fd)); return -CMD_EXP_ERR_OPEN_DEVICE; } retval = os_disk_get_size(fd, &device_size); if (retval < 0) { exalog_error("os_disk_get_size() error=%s", exa_error_msg(retval)); if (close(fd) != 0) exalog_error("can't EVEN close dev '%s'", device_path); return -EXA_ERR_IOCTL; } retval = close(fd); if (retval < 0) { retval = -errno; exalog_error("cannot close device '%s' error=%s ", device_path, exa_error_msg(retval)); return -CMD_EXP_ERR_CLOSE_DEVICE; } *nb_sectors = device_size / SECTOR_SIZE; /* remove the size of the reserved area for storing admind info */ *nb_sectors -= RDEV_RESERVED_AREA_IN_SECTORS; /* Align the size on 1K * this is the best we can do to have the same size of devices on 2.4 and 2.6 kernels due to * the fact that kernel 2.4 rounds the size of devices with 1 K */ *nb_sectors -= *nb_sectors % (1024 / SECTOR_SIZE); return EXA_SUCCESS; }