Пример #1
0
static int freeze_fs(struct ploop_copy_handle *h)
{
	int ret;

	if (h->mntfd != -1) {
		/* Sync fs */
		ploop_dbg(4, "SYNCFS");
		if (sys_syncfs(h->mntfd)) {
			ploop_err(errno, "syncfs() failed");
			ret = SYSEXIT_FSYNC;
			goto err;
		}

		/* Flush journal and freeze fs (this also clears the fs dirty bit) */
		ploop_dbg(4, "FIFREEZE");
		ret = ioctl_device(h->mntfd, FIFREEZE, 0);
		if (ret)
			goto err;

		h->fs_frozen = 1;
	}

	ploop_dbg(4, "IOC_SYNC");
	ret = ioctl_device(h->devfd, PLOOP_IOC_SYNC, 0);
	if (ret)
		goto err;

	return 0;
err:
	ploop_copy_release(h);
	return ret;
}
Пример #2
0
void ploop_copy_release(struct ploop_copy_handle *h)
{
	if (h == NULL)
		return;


	if (h->fs_frozen) {
		(void)ioctl_device(h->mntfd, FITHAW, 0);
		h->fs_frozen = 0;
	}

	if (h->tracker_on) {
		(void)ioctl_device(h->devfd, PLOOP_IOC_TRACK_ABORT, 0);
		h->tracker_on = 0;
	}

	if (h->mntfd != -1) {
		close(h->mntfd);
		h->mntfd = -1;
	}

	if (h->devfd != -1) {
		close(h->devfd);
		h->devfd = -1;
	}

	if (h->idelta.fd != -1)
		close_delta(&h->idelta);
}
Пример #3
0
int ploop_copy_start(struct ploop_copy_handle *h,
		struct ploop_copy_stat *stat)
{
	int ret;
	struct ploop_track_extent e;
	ssize_t n;
	__u64 pos;

	ret = pthread_create(&h->send_th, NULL, sender_thread, h);
	if (ret) {
		ploop_err(ret, "Can't create send thread");
		ret = SYSEXIT_SYS;
		goto err;
	}

	pthread_barrier_wait(&h->sd.barrier);

	ploop_dbg(3, "pcopy track init");
	ret = ioctl_device(h->devfd, PLOOP_IOC_TRACK_INIT, &e);
	if (ret)
		goto err;

	h->tracker_on = 1;
	h->trackend = e.end;
	ploop_log(3, "pcopy start %s e.end=%" PRIu64,
			h->async ? "async" : "", (uint64_t)e.end);
	for (pos = 0; pos <= h->trackend; ) {
		h->trackpos = pos + h->cluster;
		ret = ioctl_device(h->devfd, PLOOP_IOC_TRACK_SETPOS, &h->trackpos);
		if (ret)
			goto err;

		ret = send_image_block(h, h->cluster, pos, &n);
		if (ret)
			goto err;
		if (n == 0) /* EOF */
			break;

		pos += n;
		if (pos > h->eof_offset)
			h->eof_offset = pos;
	}

	wait_sender(h);

	stat->xferred_total = stat->xferred = pos;
	send_cmd(h, PCOPY_CMD_SYNC);
	ploop_dbg(3, "pcopy start finished");

	return 0;
err:
	ploop_copy_release(h);

	return ret;
}
Пример #4
0
int ploop_complete_running_operation(const char *device)
{
	struct ploop_balloon_ctl b_ctl;
	int fd, ret;

	fd = open_device(device);
	if (fd == -1)
		return SYSEXIT_OPEN;

	bzero(&b_ctl, sizeof(b_ctl));
	b_ctl.keep_intact = 1;
	ret = ioctl(fd, PLOOP_IOC_BALLOON, &b_ctl);
	if (ret) {
		ploop_err(errno, "Unable to get in-kernel maintenance state");
		ret = SYSEXIT_DEVIOC;
		goto err;
	}
	if (b_ctl.mntn_type == PLOOP_MNTN_OFF)
		goto err;

	ploop_log(0, "Completing an on-going operation %s for device %s",
		mntn2str(b_ctl.mntn_type), device);

	switch (b_ctl.mntn_type) {
	case PLOOP_MNTN_MERGE:
		ret = ioctl_device(fd, PLOOP_IOC_MERGE, 0);
		break;
	case PLOOP_MNTN_GROW:
		ret = ioctl_device(fd, PLOOP_IOC_GROW, 0);
		break;
	case PLOOP_MNTN_RELOC:
	case PLOOP_MNTN_FBLOADED:
		ret = ploop_balloon_complete(device);
		break;
	case PLOOP_MNTN_TRACK:
		ret = ioctl_device(fd, PLOOP_IOC_TRACK_ABORT, 0);
		break;
	case PLOOP_MNTN_DISCARD:
		ret = ploop_balloon_complete(device);
		break;
	case PLOOP_MNTN_BALLOON:
		/*  FIXME : ploop_balloon_check_and_repair(device, mount_point, 1; */
		ret = 0;
		break;
	}

err:
	close(fd);
	return ret;
}
Пример #5
0
static int freeze(struct ploop_copy_handle *h)
{
	int ret;

	ret = ioctl(h->partfd, PLOOP_IOC_FREEZE);
	if (ret) {
		if (errno == EINVAL)
			ret = freeze_fs(h);
		else
			ploop_err(errno, "Failed to freeze device");
		if (ret)
			goto err;

	} else {
		ploop_log(0, "Freezing device...");
		h->dev_frozen = 1;
	}

	ploop_dbg(3, "IOC_SYNC");
	ret = ioctl_device(h->devfd, PLOOP_IOC_SYNC, 0);
	if (ret)
		goto err;

	return 0;
err:
	ploop_copy_release(h);
	return ret;
}
Пример #6
0
Файл: main.c Проект: Alamot/3dsp
/*remove device, when success, it return the device's serialno, when failure, return TDSP_SERIAL_NOCARD 0X10000*/
int tdsp_remove_device(unsigned long serialno)
{
  int fd;
  BUSENUM_UNPLUG_HARDWARE unplug;
  int bytes;

  debug("call the function: tdsp_remove_device( %ld)\n", serialno);
  fd = open_device(TDSP_BUS_DEVICE_NAME);
  if (fd == -1)
  {
    perror("open error");
    return TDSP_SERIAL_NO_NOCARD;
  }

  unplug.Size = bytes = sizeof(unplug);
  unplug.SerialNo = serialno;
  if (ioctl_device(fd, TDSP_UNPLUG, &unplug) == -1)
  {
    close_device(fd);
    perror("tdsp_remove_device: ioctl error");
    return TDSP_SERIAL_NO_NOCARD;
  }
  close_device(fd);
  debug("tdsp_remove_device( %ld ): success\n", serialno);
  return serialno;
}
Пример #7
0
Файл: main.c Проект: Alamot/3dsp
int tdsp_query_power_state()
{
  int fd;
  int ret;
  debug("call the function: tdsp_query_power_state()\n");
  g_buspowerstate = PowerOff;
  fd = open_device(TDSP_BUS_DEVICE_NAME);
  if (fd == -1)
  {
    debug(":open file error, fail!\n");
    perror("open error");
    return TDSP_SERIAL_NO_NOCARD;
  }
  if (ioctl_device(fd, TDSP_QUERY_BUS_POWER_STATE, &ret) != 0)
  {
    close_device(fd);
    debug(": ioctl error, fail!\n");
    perror("ioctl error");
    return TDSP_SERIAL_NO_NOCARD;
  }
  close_device(fd);
  debug(": ret = 0x%x\n", ret);
  g_buspowerstate = ret;
  return ret;
}
Пример #8
0
Файл: main.c Проект: Alamot/3dsp
int tdsp_query_device()
{
  debug("call the function: tdsp_query_device \n");
  int fd;
  int ret;
  g_iscardin = FALSE;
  g_currentserialno = TDSP_SERIAL_NO_NOCARD;

  fd = open_device(TDSP_BUS_DEVICE_NAME);
  if (fd == -1)
  {
    perror("open error");
    return TDSP_SERIAL_NO_NOCARD;
  }
  if (ioctl_device(fd, TDSP_DISPLAY_IN_USE, &ret) == -1)
  {
    close_device(fd);
    perror("ioctl error");
    return TDSP_SERIAL_NO_NOCARD;
  }
  // debug ("tdsp_query_device: ret = 0x%x\n",ret); 
  close_device(fd);
  g_currentserialno = ret;
  g_iscardin = TRUE;
  debug("\ttdsp_query_device: g_iscardin = %d and g_currentserialno = 0x%x\n",
        g_iscardin, g_currentserialno);

  return ret;
}
Пример #9
0
static int blk_discard(int fd, __u32 cluster, __u64 start, __u64 len)
{
	__u64 max_discard_len = S2B(B2S(UINT_MAX) / cluster * cluster);

	while (len > 0) {
		__u64 range[2];
		int ret;

		range[0] = start;
		range[1] = MIN(len, max_discard_len);

		if (start % S2B(cluster) && len > range[1])
			range[1] -= start % S2B(cluster);

		ploop_log(1, "Call BLKDISCARD start=%" PRIu64 " length=%" PRIu64, (uint64_t)range[0], (uint64_t)range[1]);
		ret = ioctl_device(fd, BLKDISCARD, range);
		if (ret)
			return ret;

		start += range[1];
		len -= range[1];
	}

	return 0;
}
Пример #10
0
Файл: main.c Проект: Alamot/3dsp
int tdsp_query_reset_flag()
{
  int fd;
  int ret;
  g_busresetflag = 0;
  debug("call the function: tdsp_query_reset_flag()\n");
  fd = open_device(TDSP_BUS_DEVICE_NAME);
  if (fd == -1)
  {
    perror("open error");
    return -1;
  }
  if (ioctl_device(fd, TDSP_QUERY_RESET_FLAG, &ret) == -1)
  {
    close_device(fd);
    perror("ioctl error");
    return -1;
  }
  close_device(fd);
  debug
    ("the function: tdsp_query_reset_flag: ret =  %d (0 is right, 1 is no right)\n",
     ret);
  g_busresetflag = ret;
  return ret;
}
Пример #11
0
int ploop_balloon_complete(const char *device)
{
	int fd, err;
	struct ploop_balloon_ctl b_ctl;

	fd = open_device(device);
	if (fd == -1)
		return SYSEXIT_OPEN;

	err = ioctl(fd, PLOOP_IOC_DISCARD_FINI);
	if (err && errno != EBUSY) {
		ploop_err(errno, "Can't finalize discard mode");
		err = SYSEXIT_DEVIOC;
		goto out;
	}

	memset(&b_ctl, 0, sizeof(b_ctl));
	b_ctl.keep_intact = 1;
	err = ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl);
	if (err)
		goto out;

	switch (b_ctl.mntn_type) {
	case PLOOP_MNTN_BALLOON:
	case PLOOP_MNTN_MERGE:
	case PLOOP_MNTN_GROW:
	case PLOOP_MNTN_TRACK:
	case PLOOP_MNTN_OFF:
		ploop_log(0, "Nothing to complete: kernel is in \"%s\" state",
			mntn2str(b_ctl.mntn_type));
		goto out;
	case PLOOP_MNTN_RELOC:
	case PLOOP_MNTN_FBLOADED:
		break;
	default:
		ploop_err(0, "Error: unknown mntn_type (%u)",
			b_ctl.mntn_type);
		err = SYSEXIT_PROTOCOL;
		goto out;
	}

	err = ploop_balloon_relocation(fd, &b_ctl, device);
out:
	close(fd);
	return err;
}
Пример #12
0
Файл: main.c Проект: Alamot/3dsp
int tdsp_read_register(unsigned long uloffset, unsigned long ullength,
                       char *chbuf)
{
  debug("call the function: tdsp_read_register( offset=%ld,length=%ld)\n",
        uloffset, ullength);
  int fd;
  int bytes;
  PRW_REGISTER_STRUC pregister;

  fd = open_device(TDSP_BUS_DEVICE_NAME);
  if (fd == -1)
  {
    perror("open error");
    return FALSE;
  }
  pregister = (PRW_REGISTER_STRUC)
    malloc(bytes = (sizeof(RW_REGISTER_STRUC) + ullength + 1));
  if (pregister == NULL)
  {
    debug("tdsp_read_register: malloc pregister error\n");
    close_device(fd);
    return FALSE;
  }
  pregister->offset = uloffset;
  pregister->length = ullength;

  debug("the pregister: pregister->offse=%d,pregister->length=%ld\n",
        pregister->offset, pregister->length);
  if (ioctl_device(fd, TDSP_READ_REGISTER, pregister) == -1)
  {
    free(pregister);
    close_device(fd);
    printf("tdsp_read_register: ioctl error");
    return FALSE;
  }
  close_device(fd);
  pregister->buf[ullength + 1] = '\0';
  if (chbuf != NULL)
    memcpy(chbuf, pregister->buf, ullength);
  BtPrintBuffer(pregister->buf, ullength);
  free(pregister);
  return TRUE;
}
Пример #13
0
Файл: gpt.c Проект: varung/ploop
static int blkpg_resize_partition(int fd, struct GptEntry *pe)
{
	struct blkpg_ioctl_arg ioctl_arg;
	struct blkpg_partition part;

	bzero(&part, sizeof(part));
	part.pno = 1;
	part.start = S2B(pe->starting_lba);
	part.length = S2B(pe->ending_lba - pe->starting_lba + 1);

	ploop_log(3, "update partition table start=%llu length=%llu",
			part.start, part.length);
	ioctl_arg.op = BLKPG_RESIZE_PARTITION;
	ioctl_arg.flags = 0;
	ioctl_arg.datalen = sizeof(struct blkpg_partition);
	ioctl_arg.data = &part;

	return ioctl_device(fd, BLKPG, &ioctl_arg);
}
Пример #14
0
Файл: main.c Проект: Alamot/3dsp
int tdsp_download_dsp_code(unsigned long serialno)
{
  debug("call the function: tdsp_download_dsp_code(%ld)\n ", serialno);
  // return TRUE;
  int fd;
  fd = open_device(TDSP_BUS_DEVICE_NAME);
  if (fd == -1)
  {
    printf("open error");
    return FALSE;
  }
  unsigned long dwioctlcode;
  if (serialno == TDSP_SERIAL_NO_BT)
  {
    dwioctlcode = TDSP_RELOAD_BT_CODE;
  }
  else if (serialno == TDSP_SERIAL_NO_WLAN)
  {
    dwioctlcode = TDSP_RELOAD_WLAN_CODE;
  }
  else if (serialno == TDSP_SERIAL_NO_COEXIST)
  {
    dwioctlcode = TDSP_RELOAD_COMBO_CODE;
  }
  else
  {
    debug("the serialno is incorrect !");
    close_device(fd);
    return FALSE;
  }

  if (ioctl_device(fd, dwioctlcode, NULL) == -1)
  {
    debug("DOWNLOAD DSP CODE Failed");
    close_device(fd);
    return FALSE;
  }
  usleep(200000);
  debug("Download DSP code success! \n");
  close_device(fd);
  return TRUE;
}
Пример #15
0
Файл: main.c Проект: Alamot/3dsp
int set_hotkey_flag(unsigned long mode)
{
  debug("call the function: set_hotkey_flag(%d)!\n", mode);
  int fd;
  fd = open_device(TDSP_BUS_DEVICE_NAME);
  if (fd == -1)
  {
    perror("open error");
    return -1;
  }
  if (ioctl_device(fd, TDSP_SET_HOT_FLAG, &mode) == -1)
  {
    close_device(fd);
    perror("set_hotkey_flag: ioctl error");
    return -1;
  }
  debug("set_hotkey_flag: success!\n");
  close_device(fd);
  return 0;
}
Пример #16
0
Файл: main.c Проект: Alamot/3dsp
int write_enum_mode(unsigned long mode)
{
  debug("call the function: tdsp_write_enum_mode(%d)!\n", mode);
  int fd;
  fd = open_device(TDSP_BUS_DEVICE_NAME);
  if (fd == -1)
  {
    perror("open error");
    return -1;
  }
  if (ioctl_device(fd, TDSP_WRITE_ENUM_MODE, &mode) == -1)
  {
    close_device(fd);
    perror("tdsp_write_enum_mode: ioctl error");
    return -1;
  }
  debug("tdsp_ write_enum_mode: success\n");
  close_device(fd);
  return 0;
}
Пример #17
0
Файл: main.c Проект: Alamot/3dsp
void tdsp_power_off()
{
  int fd;
  fd = open_device(TDSP_BUS_DEVICE_NAME);
  if (fd == -1)
  {
    perror("open error");
    return;
  }

  debug("tdsp_bus_power_off ... wait ...\n");
  if (ioctl_device(fd, TDSP_POWER_OFF, NULL) == -1)
  {
    close_device(fd);
    perror("tdsp_power_off: ioctl error ");
    return;
  }
  debug("tdsp_power_off: success\n");
  close_device(fd);
  return;
}
Пример #18
0
Файл: main.c Проект: Alamot/3dsp
int tdsp_write_eeprom(unsigned long uloffset, unsigned long ullength,
                      char *chbuf)
{
  debug
    ("call the function: tdsp_write_eeprom( offset=%ld,length=%ld,buf=\"%s\")\n",
     uloffset, ullength, chbuf);
  int fd;
  int bytes;
  PLOAD_EEPROM_STRUC peeprom;

  fd = open_device(TDSP_BUS_DEVICE_NAME);
  if (fd == -1)
  {
    perror("open error");
    return FALSE;
  }
  peeprom = (PLOAD_EEPROM_STRUC)
    malloc(bytes = (sizeof(LOAD_EEPROM_STRUC) + ullength));
  if (peeprom == NULL)
  {
    debug("tdsp_write_eeprom: malloc peeprom error\n");
    close_device(fd);
    return FALSE;
  }
  peeprom->offset = uloffset;
  peeprom->length = ullength;
  memcpy(peeprom->buf, chbuf, ullength);
  debug("the peeprom: peeprom->offse=%d,tpeeprom->length=%ld,peeprom->buf=%s\n",
        peeprom->offset, peeprom->length, peeprom->buf);
  if (ioctl_device(fd, TDSP_WRITE_EEPROM, peeprom) == -1)
  {
    free(peeprom);
    close_device(fd);
    perror("tdsp_write_eeprom: ioctl error");
    return FALSE;
  }
  free(peeprom);
  close_device(fd);
  return TRUE;
}
Пример #19
0
Файл: main.c Проект: Alamot/3dsp
int tdsp_set_init_flag(unsigned long mode)
{
  debug("call the function:tdsp_set_init_flag( %ld)\n", mode);
  int fd;
  int ret = mode;
  fd = open_device(TDSP_BUS_DEVICE_NAME);
  if (fd == -1)
  {
    perror("openerror");
    return FALSE;
  }
  if (ioctl_device(fd, TDSP_SET_INIT_FLAG, &ret) == -1)
  {
    close_device(fd);
    perror("ioctlerror");
    return FALSE;
  }
  close_device(fd);

  debug("\ttdsp_set_init_flag success\n");
  return TRUE;
}
Пример #20
0
Файл: main.c Проект: Alamot/3dsp
int read_enum_mode()
{
  int fd;
  unsigned long ret;
  debug("call the function: read_enum_mode \n");
  fd = open_device(TDSP_BUS_DEVICE_NAME);
  if (fd == -1)
  {
    perror("open error");
    return -1;
  }
  if (ioctl_device(fd, TDSP_READ_ENUM_MODE, &ret) != 0)
  {
    close_device(fd);
    perror("ioctl error");
    return -1;
  }
  debug("get read_enum_mode is: ret = 0x%x\n", ret);
  close_device(fd);
  g_rawenummode = ret;
  return ret;
}
Пример #21
0
Файл: main.c Проект: Alamot/3dsp
/*plugin device, when success, it return the device's serialno, when failure,
return TDSP_SERIAL_NOCARD 0X10000*/
int tdsp_add_device(char *devicename, unsigned long namelen,
                    unsigned long serialno)
{
  int fd;
  int bytes;
  PBUSENUM_PLUGIN_HARDWARE hardware;
  debug("call the function: tdsp_add_device(%s, %ld, %ld)!\n", devicename,
        namelen, serialno);
  fd = open_device(TDSP_BUS_DEVICE_NAME);
  if (fd == -1)
  {
    perror("open error");
    return TDSP_SERIAL_NO_NOCARD;
  }
  hardware = (PBUSENUM_PLUGIN_HARDWARE)
    malloc(bytes = (sizeof(BUSENUM_PLUGIN_HARDWARE) + namelen));
  if (hardware == NULL)
  {
    debug("tdsp_add_device: malloc hardware error\n");
    close_device(fd);
    return TDSP_SERIAL_NO_NOCARD;
  }
  hardware->Size = sizeof(BUSENUM_PLUGIN_HARDWARE);
  hardware->SerialNo = serialno;
  memcpy(hardware->HardwareIDs, devicename, namelen);
  // debug ("tdsp_add_device: namelen = %d, total len = %d, the serialno is:%d\n", namelen, bytes,serialno);  
  if (ioctl_device(fd, TDSP_PLUGIN, hardware) == -1)
  {
    free(hardware);
    close_device(fd);
    perror("tdsp_add_device: ioctl error");
    return TDSP_SERIAL_NO_NOCARD;
  }
  debug("tdsp_add_device: success!the serialno is %d\n", serialno);
  free(hardware);
  close_device(fd);
  return serialno;
}
Пример #22
0
static int freeze_fs(struct ploop_copy_handle *h)
{
	int ret;

	if (h->mntfd != -1) {
		/* Sync fs */
		ploop_log(0, "Freezing fs...");
		if (sys_syncfs(h->mntfd)) {
			ploop_err(errno, "syncfs() failed");
			return SYSEXIT_FSYNC;
		}

		/* Flush journal and freeze fs (this also clears the fs dirty bit) */
		ploop_dbg(3, "FIFREEZE");
		ret = ioctl_device(h->mntfd, FIFREEZE, 0);
		if (ret)
			return ret;

		h->fs_frozen = 1;
	}

	return 0;
}
Пример #23
0
Файл: main.c Проект: Alamot/3dsp
int tdsp_download_dsp_code_from_file(unsigned long serialno)
{
  debug("call the function: tdsp_download_dsp_code_from_file(%ld)\n ",
        serialno);
  // return TRUE;
  int fd;
  fd = open_device(TDSP_BUS_DEVICE_NAME);
  if (fd == -1)
  {
    printf("open error");
    close_device(fd);
    return FALSE;
  }
  if (ioctl_device(fd, TDSP_RELOAD_CODE_FROM_FILE, &serialno) == -1)
  {
    debug("DOWNLOAD DSP CODE FROM FILE  Failed\n");
    close_device(fd);
    return FALSE;
  }
  usleep(200000);
  debug("Download DSP code from file success! \n");
  close_device(fd);
  return TRUE;
}
Пример #24
0
Файл: main.c Проект: Alamot/3dsp
int tdsp_query_pnp_state(unsigned long mode)
{
  debug("call the function: tdsp_query_pnp_state(%ld) \n", mode);
  int fd;
  int ret = mode;
  g_dsppnpstate = UnKnown;
  fd = open_device(TDSP_BUS_DEVICE_NAME);
  if (fd == -1)
  {
    perror("openerror");
    return 4;
  }
  if (ioctl_device(fd, TDSP_QUERY_DEVICE_STATE, &ret) == -1)
  {
    close_device(fd);
    perror("ioctlerror");
    return 4;
  }
  close_device(fd);

  g_dsppnpstate = (DEVICE_PNP_STATE) ret;
  debug("tdsp_query_pnp_state success: g_dsppnpstate = 0x%x\n", ret);
  return ret;
}
Пример #25
0
int ploop_balloon_clear_state(const char *device)
{
	int fd, ret;
	struct ploop_balloon_ctl b_ctl;

	fd = open_device(device);
	if (fd == -1)
		return SYSEXIT_OPEN;

	bzero(&b_ctl, sizeof(b_ctl));
	ret = ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl);
	if (ret)
		goto err;

	if (b_ctl.mntn_type != PLOOP_MNTN_OFF) {
		ploop_err(0, "Can't clear stale in-kernel \"BALLOON\" "
				"maintenance state because kernel is in \"%s\" "
				"state now", mntn2str(b_ctl.mntn_type));
		ret = SYSEXIT_EBUSY;
	}
err:
	close(fd);
	return ret;
}
Пример #26
0
int ploop_balloon_check_and_repair(const char *device, const char *mount_point, int repair)
{
	int   ret, fd = -1;
	int   balloonfd = -1;
	__u32 n_free_blocks;
	__u32 freezed_a_h;
	__u32 dev_start;  /* /sys/block/ploop0/ploop0p1/start */
	struct ploop_balloon_ctl    b_ctl;
	struct stat		    st;
	struct pfiemap		   *pfiemap  = NULL;
	struct freemap		   *freemap  = NULL;
	struct freemap		   *rangemap = NULL;
	struct relocmap		   *relocmap = NULL;
	struct ploop_freeblks_ctl  *freeblks = NULL;
	struct ploop_relocblks_ctl *relocblks= NULL;
	char *msg = repair ? "repair" : "check";
	__u32 *reverse_map = NULL;
	__u32  reverse_map_len;
	int top_level;
	int entries_used;
	struct delta delta = {};
	int drop_state = 0;

	ret = get_balloon(mount_point, &st, &balloonfd);
	if (ret)
		return ret;

	if (st.st_size == 0) {
		ploop_log(0, "Nothing to do: hidden balloon is empty");
		close(balloonfd);
		return 0;
	}

	pfiemap = fiemap_alloc(128);
	freemap = freemap_alloc(128);
	rangemap = freemap_alloc(128);
	relocmap = relocmap_alloc(128);
	if (!pfiemap || !freemap || !rangemap || !relocmap) {
		ret = SYSEXIT_MALLOC;
		goto err;
	}

	fd = open_device(device);
	if (fd == -1) {
		ret = SYSEXIT_OPEN;
		goto err;
	}

	memset(&b_ctl, 0, sizeof(b_ctl));
	/* block other maintenance ops even if we only check balloon */
	b_ctl.inflate = 1;
	ret = ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl);
	if (ret)
		goto err;

	switch (b_ctl.mntn_type) {
	case PLOOP_MNTN_BALLOON:
		drop_state = 1;
		ret = open_top_delta(device, &delta, &top_level);
		if (ret)
			goto err;
		reverse_map_len = delta.l2_size + delta.l2_size;
		reverse_map = alloc_reverse_map(reverse_map_len);
		if (reverse_map == NULL) {
			ret = SYSEXIT_MALLOC;
			goto err;
		}
		break;
	case PLOOP_MNTN_MERGE:
	case PLOOP_MNTN_GROW:
	case PLOOP_MNTN_TRACK:
		ploop_err(0, "Can't %s hidden balloon while another "
		       "maintenance operation is in progress (%s)",
			msg, mntn2str(b_ctl.mntn_type));
		ret = SYSEXIT_EBUSY;
		goto err;
	case PLOOP_MNTN_FBLOADED:
	case PLOOP_MNTN_RELOC:
		ploop_err(0, "Can't %s hidden balloon before previous "
			"balloon operation (%s) is completed. Use "
			"\"ploop-balloon complete\".",
			msg, mntn2str(b_ctl.mntn_type));
		ret = SYSEXIT_EBUSY;
		goto err;
	case PLOOP_MNTN_OFF:
		ploop_err(0, "Error: mntn_type is PLOOP_MNTN_OFF after "
			"IOC_BALLOON");
		ret = SYSEXIT_PROTOCOL;
		goto err;
	default:
		ploop_err(0, "Error: unknown mntn_type (%u)",
			b_ctl.mntn_type);
		ret = SYSEXIT_PROTOCOL;
		goto err;
	}

	if (dev_num2dev_start(device, st.st_dev, &dev_start)) {
		ploop_err(0, "Can't find out offset from start of ploop "
			"device (%s) to start of partition where fs (%s) "
			"resides", device, mount_point);
		ret = SYSEXIT_SYSFS;
		goto err;
	}

	ret = fiemap_get(balloonfd, S2B(dev_start), 0, st.st_size, &pfiemap);
	if (ret)
		goto err;
	fiemap_adjust(pfiemap, delta.blocksize);

	ret = fiemap_build_rmap(pfiemap, reverse_map, reverse_map_len, &delta);
	if (ret)
		goto err;

	ret = rmap2freemap(reverse_map, 0, reverse_map_len, &freemap, &entries_used);
	if (ret)
		goto err;
	if (entries_used == 0) {
		ploop_log(0, "No free blocks found");
		goto err;
	}

	ret = freemap2freeblks(freemap, top_level, &freeblks, &n_free_blocks);
	if (ret)
		goto err;
	if (!repair) {
		ploop_log(0, "Found %u free blocks. Consider using "
		       "\"ploop-balloon repair\"", n_free_blocks);
		ret = 0;
		goto err;
	} else {
		ploop_log(0, "Found %u free blocks", n_free_blocks);
	}

	ret = ioctl_device(fd, PLOOP_IOC_FREEBLKS, freeblks);
	if (ret)
		goto err;
	drop_state = 0;
	freezed_a_h = freeblks->alloc_head;
	if (freezed_a_h > reverse_map_len) {
		ploop_err(0, "Image corrupted: a_h=%u > rlen=%u",
			freezed_a_h, reverse_map_len);
		ret = SYSEXIT_PLOOPFMT;
		goto err;
	}

	ret = range_build(freezed_a_h, n_free_blocks, reverse_map, reverse_map_len,
		    &delta, freemap, &rangemap, &relocmap);
	if (ret)
		goto err;

	ret = relocmap2relocblks(relocmap, top_level, freezed_a_h, n_free_blocks,
			   &relocblks);
	if (ret)
		goto err;
	ret = ioctl_device(fd, PLOOP_IOC_RELOCBLKS, relocblks);
	if (ret)
		goto err;

	ploop_log(0, "TRUNCATED: %u cluster-blocks (%llu bytes)",
			relocblks->alloc_head,
			(unsigned long long)(relocblks->alloc_head * S2B(delta.blocksize)));

err:
	if (drop_state) {
		memset(&b_ctl, 0, sizeof(b_ctl));
		(void)ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl);
	}

	// FIXME: close_delta()
	if (balloonfd >= 0)
		close(balloonfd);
	if (fd >= 0)
		close(fd);
	free(pfiemap);
	free(freemap);
	free(rangemap);
	free(relocmap);
	free(reverse_map);
	free(freeblks);
	free(relocblks);

	return ret;
}
Пример #27
0
static int __ploop_discard(struct ploop_disk_images_data *di, int fd,
			const char *device, const char *mount_point,
			__u64 minlen_b, __u32 cluster, __u32 to_free,
			__u64 blk_discard_range[2], const int *stop)
{
	pid_t tpid;
	int err = 0, ret, status;
	__u32 size = 0;
	struct ploop_cleanup_hook *h;

	if (blk_discard_range != NULL)
		ploop_log(0, "Discard %s start=%" PRIu64 " length=%" PRIu64,
				device, (uint64_t)blk_discard_range[0], (uint64_t)blk_discard_range[1]);
	else
		ploop_log(3, "Trying to find free extents bigger than %" PRIu64 " bytes", (uint64_t)minlen_b);

	if (ploop_lock_di(di))
		return SYSEXIT_LOCK;
	ret = ioctl_device(fd, PLOOP_IOC_DISCARD_INIT, NULL);
	ploop_unlock_di(di);
	if (ret) {
		ploop_err(errno, "Can't initialize discard mode");
		return ret;
	}

	tpid = fork();
	if (tpid < 0) {
		ploop_err(errno, "Can't fork");
		ret = ioctl_device(fd, PLOOP_IOC_DISCARD_FINI, NULL);
		if (ret) {
			ploop_err(errno, "Can't finalize discard mode");
			return ret;
		}
	}

	h = register_cleanup_hook(cancel_discard, (void *) device);

	if (tpid == 0) {
		if (blk_discard_range != NULL)
			ret = blk_discard(fd, cluster, blk_discard_range[0], blk_discard_range[1]);
		else
			ret = ploop_trim(mount_point, minlen_b, cluster);
		if (ioctl_device(fd, PLOOP_IOC_DISCARD_FINI, NULL))
			ploop_err(errno, "Can't finalize discard mode");

		exit(ret != 0);
	}

	while (1) {
		struct ploop_balloon_ctl b_ctl;

		ploop_log(3, "Waiting");
		ret = ioctl(fd, PLOOP_IOC_DISCARD_WAIT, NULL);
		if (ret < 0) {
			ploop_err(errno, "Waiting for a discard request failed");
			break;
		} else if (ret == 0)
			break;

		/* FIXME PLOOP_IOC_DISCARD_WAIT should return size */
		ret = ioctl(fd, PLOOP_IOC_FBFILTER, 0);
		if (ret < 0) {
			ploop_err(errno, "Can't filter free blocks");
			break;
		} else if (ret == 0) {
			/* Nothing to do */
			ret = ioctl_device(fd, PLOOP_IOC_FBDROP, 0);
			if (ret)
				break;
			continue;
		} else
			size += ret;
		/* serialize ploop operations vs ploop_complete_running_operation()
		 * NB: PLOOP_IOC_BALLOON may change mntn from PLOOP_MNTN_DISCARD:
		 * to PLOOP_MNTN_FBLOADED
		 */
		if (ploop_lock_di(di)) {
			ret = SYSEXIT_LOCK;
			break;
		}

		memset(&b_ctl, 0, sizeof(b_ctl));
		b_ctl.keep_intact = 1;
		ret = ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl);
		if (ret) {
			ploop_unlock_di(di);
			break;
		}

		if (b_ctl.mntn_type == PLOOP_MNTN_OFF) {
			ploop_log(0, "Unexpected maintenance type 0x%x", b_ctl.mntn_type);
			ret = -1;
			ploop_unlock_di(di);
			break;
		}

		if (size >= to_free || (stop && *stop)) {
			ploop_log(3, "Killing the trim process %d", tpid);
			kill(tpid, SIGUSR1);
			ret = ioctl(fd, PLOOP_IOC_DISCARD_FINI);
			if (ret < 0 && errno != EBUSY)
				ploop_err(errno, "Can't finalize a discard mode");
		}

		ploop_log(0, "Starting relocation");
		ret = ploop_balloon_relocation(fd, &b_ctl, device);
		ploop_unlock_di(di);
		if (ret)
			break;
	}

	if (ret) {
		err = -1;

		ret = ioctl(fd, PLOOP_IOC_DISCARD_FINI);
		if (ret < 0) {
			if (errno == EBUSY)
				ploop_log(-1, "Discard finalized, but "
					"relocation is still not completed");
			else
				ploop_err(errno, "Can't finalize discard mode");
		}

		kill(tpid, SIGKILL);
	} else {
		ploop_log(0, "%d clusters have been relocated", size);
	}

	unregister_cleanup_hook(h);

	while ((ret = waitpid(tpid, &status, 0)))
		 if (errno != EINTR)
			break;
	if (ret == -1) {
		if (errno != ECHILD)
			ploop_err(errno, "wait() failed");
		err = -1;
	} else if (WIFEXITED(status)) {
		ret = WEXITSTATUS(status);
		if (ret) {
			ploop_err(0, "The trim process failed with code %d", ret);
			err = -1;
		}
	} else if (WIFSIGNALED(status)) {
		ploop_err(0, "The trim process killed by signal %d", WTERMSIG(status));
		err = -1;
	} else {
		ploop_err(0, "The trim process died abnormally");
		err = -1;
	}

	return err;
}
Пример #28
0
Файл: main.c Проект: Alamot/3dsp
int get_tdsp_version(PTDSPVERSION ver)
{
  int fd;
  unsigned char verinfo[64];
  debug("call the function: get_tdsp_version ()\n");
  fd = open_device(TDSP_BUS_DEVICE_NAME);
  if (fd == -1)
  {
    perror("open error");
    return -1;
  }

  int bsuccess;
  bsuccess = FALSE;
  if (ver->pos[0] == 1)
  {
    long serial = 1;
    memset(verinfo, '\0', 64);
    memcpy(verinfo, &serial, sizeof(serial));
    if (ioctl_device(fd, TDSP_QUERY_DEVICE_VERSION, &verinfo) == -1)
    {
      close_device(fd);
      ver->pos[0] = 0;
      perror("ioctl error");
      return -1;
    }
    else
    {
      strcpy((char *) ver->btver, (char *) verinfo);
    }
  }
  if (ver->pos[1] == 1)
  {
    long serial = 2;
    memset(verinfo, '\0', 64);
    memcpy(verinfo, &serial, sizeof(serial));
    if (ioctl_device(fd, TDSP_QUERY_DEVICE_VERSION, &verinfo) == -1)
    {
      close_device(fd);
      ver->pos[1] = 0;
      perror("ioctl error");
      return -1;
    }
    else
    {
      strcpy((char *) ver->wlanver, (char *) verinfo);
    }
  }
  if (ver->pos[2] == 1)
  {
    memset(verinfo, '\0', 64);
    if (ioctl_device(fd, TDSP_QUERY_BUS_VERSION, &verinfo) == -1)
    {
      close_device(fd);
      ver->pos[2] = 0;
      perror("ioctl error");
      return -1;
    }
    else
    {
      strcpy((char *) ver->busver, (char *) verinfo);
    }
  }
  if (ver->pos[3] == 1)
  {
    unsigned long verinfo1;
    if (ioctl_device(fd, TDSP_QUERY_FIRMWARE_VERSION, &verinfo1) == -1)
    {
      close_device(fd);
      ver->pos[3] = 0;
      perror("ioctl error");
      return -1;
    }
    else
    {
      ver->firmwarever = verinfo1;
    }
  }
  if (ver->pos[4] == 1)
  {
    unsigned long verinfo2;
    if (ioctl_device(fd, TDSP_QUERY_8051_VERSION, &verinfo2) == -1)
    {
      close_device(fd);
      ver->pos[4] = 0;
      perror("ioctl error");
      return -1;
    }
    else
    {
      ver->ver8051= verinfo2;
    }
  }
  close_device(fd);
  return TRUE;
}
Пример #29
0
int ploop_balloon_change_size(const char *device, int balloonfd, off_t new_size)
{
	int    fd = -1;
	int    ret;
	off_t  old_size;
	__u32  dev_start;  /* /sys/block/ploop0/ploop0p1/start */
	__u32  n_free_blocks;
	__u32  freezed_a_h;
	struct ploop_balloon_ctl    b_ctl;
	struct stat		    st;
	struct pfiemap		   *pfiemap = NULL;
	struct freemap		   *freemap = NULL;
	struct freemap		   *rangemap = NULL;
	struct relocmap		   *relocmap = NULL;
	struct ploop_freeblks_ctl  *freeblks = NULL;
	struct ploop_relocblks_ctl *relocblks = NULL;
	__u32 *reverse_map = NULL;
	__u32  reverse_map_len;
	int top_level;
	struct delta delta = { .fd = -1 };
	int entries_used;
	int drop_state = 0;

	if (fstat(balloonfd, &st)) {
		ploop_err(errno, "Can't get balloon file size");
		return SYSEXIT_FSTAT;
	}

	old_size = st.st_size;
	new_size = (S2B(new_size) + st.st_blksize - 1) & ~(st.st_blksize - 1);

	ploop_log(0, "Changing balloon size old_size=%ld new_size=%ld",
			(long)old_size, (long)new_size);

	pfiemap = fiemap_alloc(128);
	freemap = freemap_alloc(128);
	rangemap = freemap_alloc(128);
	relocmap = relocmap_alloc(128);
	if (!pfiemap || !freemap || !rangemap || !relocmap) {
		ret = SYSEXIT_MALLOC;
		goto err;
	}

	fd = open_device(device);
	if (fd == -1) {
		ret = SYSEXIT_OPEN;
		goto err;
	}

	memset(&b_ctl, 0, sizeof(b_ctl));
	if (old_size < new_size)
		b_ctl.inflate = 1;
	ret = ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl);
	if (ret)
		goto err;

	drop_state = 1;
	if (old_size >= new_size) {
		ret = do_truncate(balloonfd, b_ctl.mntn_type, old_size, new_size);
		goto err;
	}

	if (dev_num2dev_start(device, st.st_dev, &dev_start)) {
		ploop_err(0, "Can't find out offset from start of ploop "
			"device (%s) to start of partition",
			device);
		ret = SYSEXIT_SYSFS;
		goto err;
	}

	ret = open_top_delta(device, &delta, &top_level);
	if (ret)
		goto err;

	ret = do_inflate(balloonfd, b_ctl.mntn_type, old_size, &new_size, &drop_state);
	if (ret)
		goto err;

	reverse_map_len = delta.l2_size + delta.l2_size;
	reverse_map = alloc_reverse_map(reverse_map_len);
	if (reverse_map == NULL) {
		ret = SYSEXIT_MALLOC;
		goto err;
	}

	ret = fiemap_get(balloonfd, S2B(dev_start), old_size, new_size, &pfiemap);
	if (ret)
		goto err;
	fiemap_adjust(pfiemap, delta.blocksize);
	ret = fiemap_build_rmap(pfiemap, reverse_map, reverse_map_len, &delta);
	if (ret)
		goto err;

	ret = rmap2freemap(reverse_map, 0, reverse_map_len, &freemap, &entries_used);
	if (ret)
		goto err;
	if (entries_used == 0) {
		drop_state = 1;
		ploop_log(0, "No unused cluster blocks found");
		goto out;
	}

	ret = freemap2freeblks(freemap, top_level, &freeblks, &n_free_blocks);
	if (ret)
		goto err;
	ret = ioctl_device(fd, PLOOP_IOC_FREEBLKS, freeblks);
	if (ret)
		goto err;
	freezed_a_h = freeblks->alloc_head;
	if (freezed_a_h > reverse_map_len) {
		ploop_err(0, "Image corrupted: a_h=%u > rlen=%u",
			freezed_a_h, reverse_map_len);
		ret = SYSEXIT_PLOOPFMT;
		goto err;
	}

	ret = range_build(freezed_a_h, n_free_blocks, reverse_map, reverse_map_len,
		    &delta, freemap, &rangemap, &relocmap);
	if (ret)
		goto err;

	ret = relocmap2relocblks(relocmap, top_level, freezed_a_h, n_free_blocks,
			   &relocblks);
	if (ret)
		goto err;
	ret = ioctl_device(fd, PLOOP_IOC_RELOCBLKS, relocblks);
	if (ret)
		goto err;
	ploop_log(0, "TRUNCATED: %u cluster-blocks (%llu bytes)",
			relocblks->alloc_head,
			(unsigned long long)(relocblks->alloc_head * S2B(delta.blocksize)));
out:
	ret = 0;
err:
	if (drop_state) {
		memset(&b_ctl, 0, sizeof(b_ctl));
		(void)ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl);
	}
	if (fd != -1)
		close(fd);
	free(pfiemap);
	free(freemap);
	free(rangemap);
	free(relocmap);
	free(reverse_map);
	free(freeblks);
	free(relocblks);
	if (delta.fd != -1)
		close_delta(&delta);

	return ret;
}

int ploop_balloon_get_state(const char *device, __u32 *state)
{
	int fd, ret;
	struct ploop_balloon_ctl b_ctl;

	fd = open_device(device);
	if (fd == -1)
		return SYSEXIT_OPEN;

	bzero(&b_ctl, sizeof(b_ctl));
	b_ctl.keep_intact = 1;
	ret = ioctl_device(fd, PLOOP_IOC_BALLOON, &b_ctl);
	if (ret)
		goto err;

	*state = b_ctl.mntn_type;

err:
	close(fd);

	return ret;
}
Пример #30
0
static int ploop_balloon_relocation(int fd, struct ploop_balloon_ctl *b_ctl, const char *device)
{
	int    ret = -1;
	__u32  n_free_blocks = 0;
	__u32  freezed_a_h;
	struct freemap		   *freemap = NULL;
	struct freemap		   *rangemap = NULL;
	struct relocmap		   *relocmap = NULL;
	struct ploop_freeblks_ctl  *freeblks = NULL;
	struct ploop_relocblks_ctl *relocblks = NULL;;
	__u32 *reverse_map = NULL;
	__u32  reverse_map_len;
	int top_level;
	struct delta delta = {};

	freemap  = freemap_alloc(128);
	rangemap = freemap_alloc(128);
	relocmap = relocmap_alloc(128);
	if (freemap == NULL || rangemap == NULL || relocmap == NULL) {
		ret = SYSEXIT_MALLOC;
		goto err;
	}

	top_level   = b_ctl->level;
	freezed_a_h = b_ctl->alloc_head;

	if (b_ctl->mntn_type == PLOOP_MNTN_RELOC)
		goto reloc;

	if (b_ctl->mntn_type != PLOOP_MNTN_FBLOADED) {
		ploop_err(0, "Error: non-suitable mntn_type (%u)",
			b_ctl->mntn_type);
		ret = SYSEXIT_PROTOCOL;
		goto err;
	}

	ret = freeblks_alloc(&freeblks, 0);
	if (ret)
		goto err;
	ret = ioctl_device(fd, PLOOP_IOC_FBGET, freeblks);
	if (ret)
		goto err;

	if (freeblks->n_extents == 0)
		goto reloc;

	ret = freeblks_alloc(&freeblks, freeblks->n_extents);
	if (ret)
		goto err;
	ret = ioctl_device(fd, PLOOP_IOC_FBGET, freeblks);
	if (ret)
		goto err;

	ret = freeblks2freemap(freeblks, &freemap, &n_free_blocks);
	if (ret)
		goto err;

	ret = open_top_delta(device, &delta, &top_level);
	if (ret)
		goto err;
	reverse_map_len = delta.l2_size + delta.l2_size;
	reverse_map = alloc_reverse_map(reverse_map_len);
	if (reverse_map == NULL) {
		close_delta(&delta);
		ret = SYSEXIT_MALLOC;
		goto err;
	}

	ret = range_build(freezed_a_h, n_free_blocks, reverse_map, reverse_map_len,
		    &delta, freemap, &rangemap, &relocmap);
	close_delta(&delta);
	if (ret)
		goto err;
reloc:
	ret = relocmap2relocblks(relocmap, top_level, freezed_a_h, n_free_blocks,
			   &relocblks);
	if (ret)
		goto err;
	ret = ioctl_device(fd, PLOOP_IOC_RELOCBLKS, relocblks);
	if (ret)
		goto err;

	ploop_log(0, "TRUNCATED: %u cluster-blocks (%llu bytes)",
			relocblks->alloc_head,
			(unsigned long long)(relocblks->alloc_head * S2B(delta.blocksize)));
err:

	free(freemap);
	free(rangemap);
	free(relocmap);
	free(reverse_map);
	free(freeblks);
	free(relocblks);

	return ret;
}