Пример #1
0
bool CUDevProvider::PumpDriveChangeEvents(IStorageEventsCallback *callback)
{
  bool changed = false;

  fd_set readfds;
  FD_ZERO(&readfds);
  FD_SET(udev_monitor_get_fd(m_udevMon), &readfds);

  // non-blocking, check the file descriptor for received data
  struct timeval tv = {0};
  int count = select(udev_monitor_get_fd(m_udevMon) + 1, &readfds, NULL, NULL, &tv);
  if (count < 0)
    return false;

  if (FD_ISSET(udev_monitor_get_fd(m_udevMon), &readfds))
  {
		struct udev_device *dev = udev_monitor_receive_device(m_udevMon);
    if (!dev)
      return false;

    const char *action  = udev_device_get_action(dev);
    const char *devtype = udev_device_get_devtype(dev);
    if (action)
    {
      const char *label = udev_device_get_property_value(dev, "ID_FS_LABEL");
      const char *mountpoint = get_mountpoint(udev_device_get_devnode(dev));
      if (!label)
        label = URIUtils::GetFileName(mountpoint);

      if (!strcmp(action, "add") && !strcmp(devtype, "partition"))
      {
        CLog::Log(LOGNOTICE, "UDev: Added %s", mountpoint);
        if (callback)
          callback->OnStorageAdded(label, mountpoint);
        changed = true;
      }
      if (!strcmp(action, "remove") && !strcmp(devtype, "partition"))
      {
        CLog::Log(LOGNOTICE, "UDev: Removed %s", mountpoint);
        if (callback)
          callback->OnStorageSafelyRemoved(label);
        changed = true;
      }
    }
    udev_device_unref(dev);
  }

  return changed;
}
int oem_wipe_partition(int argc, char **argv)
{
	int retval = -1;
	char mnt_point[MOUNT_POINT_SIZE] = "";

	if (argc != 2) {
                error("oem erase called with wrong parameter!");
		goto end;
	}

	if (get_mountpoint(argv[1], mnt_point))
		goto end;

	print("CMD '%s %s'...\n", argv[0], mnt_point);

	retval = nuke_volume(mnt_point, BUFFER_SIZE);
	if (retval != 0)
		error("wipe partition failed: %s\n", mnt_point);

end:
	return retval;
}
int oem_erase_partition(int argc, char **argv)
{
	int retval = -1;
	char mnt_point[MOUNT_POINT_SIZE] = "";

	if (argc != 2) {
		/* Should not pass here ! */
                error("oem erase called with wrong parameter!");
		goto end;
	}

	if (get_mountpoint(argv[1], mnt_point))
		goto end;

	print("CMD '%s %s'...\n", argv[0], mnt_point);

	print("ERASE step 1/2...\n");
	retval = nuke_volume(mnt_point, BUFFER_SIZE);
	if (retval != 0) {
		error("format_volume failed: %s\n", mnt_point);
		goto end;
	} else {
		print("format_volume succeeds: %s\n", mnt_point);
	}

	print("ERASE step 2/2...\n");
	retval = format_volume(mnt_point);
	if (retval != 0) {
		error("format_volume failed: %s\n", mnt_point);
	} else {
		print("format_volume succeeds: %s\n", mnt_point);
	}

end:
	return retval;
}
Пример #4
0
void CUDevProvider::GetDisks(VECSOURCES& disks, bool removable)
{
  // enumerate existing block devices
  struct udev_enumerate *u_enum = udev_enumerate_new(m_udev);
  if (u_enum == NULL)
  {
    fprintf(stderr, "Error: udev_enumerate_new(udev)\n");
    return;
  }

  udev_enumerate_add_match_subsystem(u_enum, "block");
  udev_enumerate_add_match_property(u_enum, "DEVTYPE", "disk");
  udev_enumerate_add_match_property(u_enum, "DEVTYPE", "partition");
  udev_enumerate_scan_devices(u_enum);

  struct udev_list_entry *u_list_ent;
  struct udev_list_entry *u_first_list_ent;
  u_first_list_ent = udev_enumerate_get_list_entry(u_enum);
  udev_list_entry_foreach(u_list_ent, u_first_list_ent)
  {
    const char *name = udev_list_entry_get_name(u_list_ent);
    struct udev *context = udev_enumerate_get_udev(u_enum);
    struct udev_device *device = udev_device_new_from_syspath(context, name);
    if (device == NULL)
      continue;

    // filter out devices that are not mounted
    const char *mountpoint = get_mountpoint(udev_device_get_devnode(device));
    if (!mountpoint)
    {
      udev_device_unref(device);
      continue;
    }

    // filter out things mounted on /tmp
    if (strstr(mountpoint, "/tmp"))
    {
      udev_device_unref(device);
      continue;
    }

    // look for usb devices on the usb bus, or mounted on /media/usbX (sdcards) or cdroms
    const char *bus = udev_device_get_property_value(device, "ID_BUS");
    const char *cdrom = udev_device_get_property_value(device, "ID_CDROM");
    if (removable  &&
      ((bus        && strstr(bus, "usb")) ||
       (cdrom      && strstr(cdrom,"1"))  ||
       (mountpoint && strstr(mountpoint, "/media/"))))
    {
      const char *label = udev_device_get_property_value(device, "ID_FS_LABEL");
      if (!label)
        label = URIUtils::GetFileName(mountpoint);

      CMediaSource share;
      share.strName  = label;
      share.strPath  = mountpoint;
      share.m_ignore = true;
      share.m_iDriveType = CMediaSource::SOURCE_TYPE_REMOVABLE;
      AddOrReplace(disks, share);
    }
    udev_device_unref(device);
  }
  udev_enumerate_unref(u_enum);
}
Пример #5
0
int main(int argc, char *argv[]) {

	//todo: add param for specific array

	char mdstat[] = "mdstat";
	char mtab[]   = "mounts";
	char fstab[]  = "fstab";

	int foobar;

	char line[80];
	char *ptr = NULL;
	char *tmp = NULL;
	char delim[2] = ":";
	const char devname[22];
	const char *uuid = NULL;

	FILE *fd;
	fd = fopen(mdstat, "r");

	if (fd == NULL) {
    	printf("Error: Could not open file %s", mdstat);
    	return 1;
	} else {


	/*******************************************/
	/* Getting number of arrays   	           */
	/*******************************************/

	int arr_count = 0;
	int i = 0;

	while(fgets(line,80,fd) != NULL) {

  		//todo: status, metadaten, member

  		ptr = strtok(line, delim);

  		if(ptr != NULL) {
    		tmp = truncate_whitespace(ptr, strlen(ptr));
  		}

  		if (strcmp(tmp, "Personalities") == 0)
			continue;

  		if (strcmp(tmp, "read_ahead") == 0)
       		continue;

  		if (strcmp(tmp, "unused") == 0)
      		continue;

  		if (tmp[0] == '\n')
			continue;

  		if (strlen(tmp) < 1)
      		continue;


  		if((strlen(tmp) > 0) && tmp[0] != '\n') {
    		arr_count++;
  		}

	}

	md_array cur_array[arr_count];

	/*******************************************/
	/* Getting the array name and skipping the */
	/* "Personalities"		           */
	/* "read_ahead"			           */
	/* "unused" lines		           */
	/*******************************************/

	rewind(fd);
	char *p = NULL;

	while(fgets(line,80,fd) != NULL) {

		if(strstr(line, "raid") != NULL) {

  		//Found a valid array line


        	p=strstr(line, "raid0");
        	if(p != NULL) {
        		cur_array[i].personality = 0;
   			}

        	p=strstr(line, "raid1");
        	if(p != NULL) {
        		cur_array[i].personality = 1;
        	}

        	p=strstr(line, "raid5");
        	if(p != NULL) {
        		cur_array[i].personality = 5;
  			}

        	p=strstr(line, "raid6");
        	if(p != NULL) {
        		cur_array[i].personality = 6;
  			}

        	p=strstr(line, "raid10");
        	if(p != NULL) {
        		cur_array[i].personality = 10;
  			}
	}

 	ptr = strtok(line, delim);

  	if(ptr != NULL) {
    	tmp = truncate_whitespace(ptr, strlen(ptr));
  	}

  	if (strcmp(tmp, "Personalities") == 0)
    	continue;

  	if (strcmp(tmp, "read_ahead") == 0)
       	continue;

  	if (strcmp(tmp, "unused") == 0)
      	continue;

  	if (tmp[0] == '\n')
        continue;

  	if (strlen(tmp) < 1)
      	continue;

	snprintf(cur_array[i].name, sizeof cur_array[i].name, tmp);
  	snprintf(cur_array[i].devpath, sizeof cur_array[i].devpath, "%s%s", "/dev/", cur_array[i].name);

  	uuid = map_uuid(cur_array[i].devpath);

  	if((strlen(uuid) != 36)) {
    	uuid = "N/A";
      	snprintf(cur_array[i].uuid, sizeof cur_array[i].uuid, uuid);
  	} else {
    	snprintf(cur_array[i].uuid, sizeof cur_array[i].uuid, uuid);
    }


  	snprintf(cur_array[i].mnt, sizeof cur_array[i].mnt, get_mountpoint(cur_array[i].devpath, mtab));
	snprintf(cur_array[i].fstab, sizeof cur_array[i].fstab, 
	get_mountpoint(cur_array[i].devpath, fstab));
  	cur_array[i].degraded = 0;
  	cur_array[i].member_count = 0;
  	cur_array[i].members = "";

  	i++;

	}


	fclose(fd);

  	for (i = 0; i < arr_count; i++) {

  		print_array_information(cur_array, i);
  		printf("----------------------------------------------------------\n");
  	}

}

	return 0;

}
Пример #6
0
bool CUDevProvider::PumpDriveChangeEvents(IStorageEventsCallback *callback)
{
  bool changed = false;

  fd_set readfds;
  FD_ZERO(&readfds);
  FD_SET(udev_monitor_get_fd(m_udevMon), &readfds);

  // non-blocking, check the file descriptor for received data
  struct timeval tv = {0};
  int count = select(udev_monitor_get_fd(m_udevMon) + 1, &readfds, NULL, NULL, &tv);
  if (count < 0)
    return false;

  if (FD_ISSET(udev_monitor_get_fd(m_udevMon), &readfds))
  {
		struct udev_device *dev = udev_monitor_receive_device(m_udevMon);
    if (!dev)
      return false;

    const char *action  = udev_device_get_action(dev);
    if (action)
    {
      std::string label;
      const char *udev_label = udev_device_get_property_value(dev, "ID_FS_LABEL");
      const char *mountpoint = get_mountpoint(udev_device_get_devnode(dev));
      if (udev_label)
        label = udev_label;
      else if (mountpoint)
        label = URIUtils::GetFileName(mountpoint);

      const char *fs_usage = udev_device_get_property_value(dev, "ID_FS_USAGE");
      if (mountpoint && strcmp(action, "add") == 0 && (fs_usage && strcmp(fs_usage, "filesystem") == 0))
      {
        CLog::Log(LOGNOTICE, "UDev: Added %s", mountpoint);
        if (callback)
          callback->OnStorageAdded(label, mountpoint);
        changed = true;
      }
      if (strcmp(action, "remove") == 0 && (fs_usage && strcmp(fs_usage, "filesystem") == 0))
      {
        if (callback)
          callback->OnStorageSafelyRemoved(label);
        changed = true;
      }
      if (strcmp(action, "change") == 0)
      {
        if (mountpoint)
        {
          CLog::Log(LOGNOTICE, "UDev: Changed / Added %s", mountpoint);
          if (callback)
            callback->OnStorageAdded(label, mountpoint);
          changed = true;
        }
        const char *eject_request = udev_device_get_property_value(dev, "DISK_EJECT_REQUEST");
        if (eject_request && strcmp(eject_request, "1") == 0)
        {
          if (callback)
            callback->OnStorageSafelyRemoved(label);
          changed = true;
        }
      }
    }
    udev_device_unref(dev);
  }

  return changed;
}
Пример #7
0
void CUDevProvider::GetDisks(VECSOURCES& disks, bool removable)
{
  // enumerate existing block devices
  struct udev_enumerate *u_enum = udev_enumerate_new(m_udev);
  if (u_enum == NULL)
  {
    fprintf(stderr, "Error: udev_enumerate_new(udev)\n");
    return;
  }

  udev_enumerate_add_match_subsystem(u_enum, "block");
  udev_enumerate_add_match_property(u_enum, "DEVTYPE", "disk");
  udev_enumerate_add_match_property(u_enum, "DEVTYPE", "partition");
  udev_enumerate_scan_devices(u_enum);

  struct udev_list_entry *u_list_ent;
  struct udev_list_entry *u_first_list_ent;
  u_first_list_ent = udev_enumerate_get_list_entry(u_enum);
  udev_list_entry_foreach(u_list_ent, u_first_list_ent)
  {
    const char *name = udev_list_entry_get_name(u_list_ent);
    struct udev *context = udev_enumerate_get_udev(u_enum);
    struct udev_device *device = udev_device_new_from_syspath(context, name);
    if (device == NULL)
      continue;

    // filter out devices that are not mounted
    const char *mountpoint = get_mountpoint(udev_device_get_devnode(device));
    if (!mountpoint)
    {
      udev_device_unref(device);
      continue;
    }

    // filter out root partition
    if (strcmp(mountpoint, "/") == 0)
    {
      udev_device_unref(device);
      continue;
    }

    // filter out things mounted on /tmp
    if (strstr(mountpoint, "/tmp"))
    {
      udev_device_unref(device);
      continue;
    }

    // look for devices on the usb bus, or mounted on */media/ (sdcards), or optical devices
    const char *bus = udev_device_get_property_value(device, "ID_BUS");
    const char *optical = udev_device_get_property_value(device, "ID_CDROM"); // matches also DVD, Blu-ray
    bool isRemovable = ((bus        && strstr(bus, "usb")) ||
                        (optical    && strstr(optical,"1"))  ||
                        (mountpoint && strstr(mountpoint, "/media/")));

    // filter according to requested device type
    if (removable != isRemovable)
    {
      udev_device_unref(device);
      continue;
    }

    const char *udev_label = udev_device_get_property_value(device, "ID_FS_LABEL");
    std::string label;
    if (udev_label)
      label = udev_label;
    else
      label = URIUtils::GetFileName(mountpoint);

    CMediaSource share;
    share.strName  = label;
    share.strPath  = mountpoint;
    share.m_ignore = true;
    if (isRemovable)
    {
      if (optical)
        share.m_iDriveType = CMediaSource::SOURCE_TYPE_DVD;
      else
        share.m_iDriveType = CMediaSource::SOURCE_TYPE_REMOVABLE;
    }
    else
      share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL;

    disks.push_back(share);
    udev_device_unref(device);
  }
  udev_enumerate_unref(u_enum);
}
Пример #8
0
int main(int argc, char *argv[])
{
	if(argc<2)
	{
		std::cout << "Not enough parameters" << std::endl;
		return 1;
	}
	
	std::string cmd;
	int mode = 0;
	if((std::string)argv[1]!="test")
	{
		if(argc<3)
		{
			std::cout << "Not enough parameters" << std::endl;
			return 1;
		}
		cmd=argv[2];
		mode=atoi(argv[1]);
	}
	else
	{
		cmd=argv[1];
	}

	std::string backupfolder=getBackupfolderPath(mode);
	
	if(backupfolder.empty())
	{	
		if(mode==mode_btrfs)
		{
			std::cout << "Backupfolder not set" << std::endl;
		}
		else if(mode==mode_zfs)
		{
			std::cout << "ZFS image dataset not set" << std::endl;
		}
		else if(mode==mode_zfs_file)
		{
			std::cout << "ZFS file dataset not set" << std::endl;
		}
		else
		{
			std::cout << "Unknown mode: " << mode << std::endl;
		}
		return 1;
	}
	
	if(cmd!="test" && mode==mode_zfs_file)
	{
		mode=mode_zfs;
	}
	
#ifndef _WIN32
	if(seteuid(0)!=0)
	{
		std::cout << "Cannot become root user" << std::endl;
		return 1;
	}
#endif

	if(cmd=="create")
	{
		if(argc<5)
		{
			std::cout << "Not enough parameters for create" << std::endl;
			return 1;
		}

		std::string clientname=handleFilename(argv[3]);
		std::string name=handleFilename(argv[4]);

		std::string subvolume_folder=backupfolder+os_file_sep()+clientname+os_file_sep()+name;
		
		return create_subvolume(mode, subvolume_folder)?0:1;
	}
	else if(cmd=="mountpoint")
	{
		if(argc<5)
		{
			std::cout << "Not enough parameters for mountpoint" << std::endl;
			return 1;
		}

		std::string clientname=handleFilename(argv[3]);
		std::string name=handleFilename(argv[4]);

		std::string subvolume_folder=backupfolder+os_file_sep()+clientname+os_file_sep()+name;
		
		return get_mountpoint(mode, subvolume_folder)?0:1;
	}
	else if(cmd=="snapshot")
	{
		if(argc<6)
		{
			std::cout << "Not enough parameters for snapshot" << std::endl;
			return 1;
		}

		std::string clientname=handleFilename(argv[3]);
		std::string src_name=handleFilename(argv[4]);
		std::string dst_name=handleFilename(argv[5]);

		std::string subvolume_src_folder=backupfolder+os_file_sep()+clientname+os_file_sep()+src_name;
		std::string subvolume_dst_folder=backupfolder+os_file_sep()+clientname+os_file_sep()+dst_name;

		return create_snapshot(mode, subvolume_src_folder, subvolume_dst_folder)?0:1;
	}
	else if(cmd=="remove")
	{
		if(argc<5)
		{
			std::cout << "Not enough parameters for remove" << std::endl;
			return 1;
		}

		std::string clientname=handleFilename(argv[3]);
		std::string name=handleFilename(argv[4]);

		std::string subvolume_folder=backupfolder+os_file_sep()+clientname+os_file_sep()+name;
		
		return remove_subvolume(mode, subvolume_folder)?0:1;
	}
	else if(cmd=="test")
	{
		std::cout << "Testing for btrfs..." << std::endl;
		std::string clientdir=backupfolder+os_file_sep()+"testA54hj5luZtlorr494";
		
		bool create_dir_rc=os_create_dir(clientdir);
		if(!create_dir_rc)
		{	
			remove_subvolume(mode_zfs, clientdir, true);
			remove_subvolume(mode_btrfs, clientdir+os_file_sep()+"A", true);
			remove_subvolume(mode_btrfs, clientdir+os_file_sep()+"B", true);
			os_remove_dir(clientdir);
		}
		create_dir_rc = create_dir_rc || os_create_dir(clientdir);
		if(create_dir_rc)
		{	
			if(!create_subvolume(mode_btrfs, clientdir+os_file_sep()+"A") )
			{
				std::cout << "TEST FAILED: Creating test btrfs subvolume failed" << std::endl;
				os_remove_dir(clientdir);
				
				return zfs_test();
			}
			
			bool suc=true;

			if(!create_snapshot(mode_btrfs, clientdir+os_file_sep()+"A", clientdir+os_file_sep()+"B") )
			{
				std::cout << "TEST FAILED: Creating test snapshot failed" << std::endl;
				suc=false;
			}
			
			if(suc)
			{			
				writestring("test", clientdir+os_file_sep()+"A"+os_file_sep()+"test");
				
				if(!os_create_hardlink(clientdir+os_file_sep()+"B"+os_file_sep()+"test", clientdir+os_file_sep()+"A"+os_file_sep()+"test", true, NULL))
				{
					std::cout << "TEST FAILED: Creating cross sub-volume reflink failed. Need Linux kernel >= 3.6." << std::endl;
					suc=false;
				}
				else
				{
					if(getFile(clientdir+os_file_sep()+"B"+os_file_sep()+"test")!="test")
					{
						std::cout << "TEST FAILED: Cannot read reflinked file" << std::endl;
						suc=false;
					}
				}
			}

			if(!remove_subvolume(mode_btrfs, clientdir+os_file_sep()+"A") )
			{
				std::cout << "TEST FAILED: Removing subvolume A failed" << std::endl;
				suc=false;
			}

			if(!remove_subvolume(mode_btrfs, clientdir+os_file_sep()+"B") )
			{
				std::cout << "TEST FAILED: Removing subvolume B failed" << std::endl;
				suc=false;
			}

			if(!os_remove_dir(clientdir))
			{
				std::cout << "TEST FAILED: Removing test clientdir failed" << std::endl;
				return 1;
			}
			
			if(!suc)
			{
				return 1;
			}
		}
		else
		{
			std::cout << "TEST FAILED: Creating test clientdir \"" << clientdir << "\" failed" << std::endl;
						
			return zfs_test();
		}
		std::cout << "BTRFS TEST OK" << std::endl;
		return 10 + mode_btrfs;
	}
	else if(cmd=="issubvolume")
	{
		if(argc<5)
		{
			std::cout << "Not enough parameters for issubvolume" << std::endl;
			return 1;
		}

		std::string clientname=handleFilename(argv[3]);
		std::string name=handleFilename(argv[4]);

		std::string subvolume_folder=backupfolder+os_file_sep()+clientname+os_file_sep()+name;
		
		return is_subvolume(mode, subvolume_folder)?0:1;
	}
	else if(cmd=="makereadonly")
	{
		if(argc<5)
		{
			std::cout << "Not enough parameters for makereadonly" << std::endl;
			return 1;
		}
		
		std::string clientname=handleFilename(argv[3]);
		std::string name=handleFilename(argv[4]);

		std::string subvolume_folder=backupfolder+os_file_sep()+clientname+os_file_sep()+name;
		
		return make_readonly(mode, subvolume_folder)?0:1;
	}
	else
	{
		std::cout << "Command not found" << std::endl;
		return 1;
	}
}