Example #1
0
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;
}
Example #2
0
static const char *find_nonexistent_disk(void)
{
    static char disk[OS_PATH_MAX];
    char drive[3] = "?:";

    /* Find first non-existent disk, skipping A: and B: (floppies)
       and C: (system) */
    for (drive[0] = 'D'; drive[0] <= 'Z'; drive[0]++)
    {
        os_disk_normalize_path(drive, disk, sizeof(disk));
        if (os_disk_open_raw(disk, OS_DISK_READ) == -ENOENT)
            return disk;
    }

    return NULL;
}
Example #3
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;
}
Example #4
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;
}