bool LibPartedPartitionTable::clobberFileSystem(Report& report, const Partition& partition)
{
    bool rval = false;

    if (PedPartition* pedPartition = ped_disk_get_partition_by_sector(pedDisk(), partition.firstSector())) {
        if (pedPartition->type == PED_PARTITION_NORMAL || pedPartition->type == PED_PARTITION_LOGICAL) {
            if (ped_device_open(pedDevice())) {
                //reiser4 stores "ReIsEr4" at sector 128 with a sector size of 512 bytes

                // We need to use memset instead of = {0} because clang sucks.
                const long long zeroes_length = pedDevice()->sector_size*129;
                char zeroes[zeroes_length];
                memset(zeroes, 0, zeroes_length*sizeof(char));

                rval = ped_geometry_write(&pedPartition->geom, zeroes, 0, 129);

                if (!rval)
                    report.line() << xi18nc("@info:progress", "Failed to erase filesystem signature on partition <filename>%1</filename>.", partition.deviceNode());

                ped_device_close(pedDevice());
            }
        } else
            rval = true;
    } else
        report.line() << xi18nc("@info:progress", "Could not delete file system on partition <filename>%1</filename>: Failed to get partition.", partition.deviceNode());

    return rval;
}
Beispiel #2
0
bool LibPartedDevice::openExclusive()
{
    bool rval = open() && ped_device_open(pedDevice());

    if (rval)
        setExclusive(true);

    return rval;
}
Beispiel #3
0
/**
 * This function opens the file system stored on \p geom, if it
 * can find one.
 * It is often called in the following manner:
 * \code
 *     fs = ped_file_system_open (&part.geom)
 * \endcode
 *
 * \throws PED_EXCEPTION_ERROR if file system could not be detected
 * \throws PED_EXCEPTION_ERROR if the file system is bigger than its volume
 * \throws PED_EXCEPTION_NO_FEATURE if opening of a file system stored on
 *     \p geom is not implemented
 *
 * \return a PedFileSystem on success, \c NULL on failure.
 */
PedFileSystem *
ped_file_system_open (PedGeometry* geom)
{
       PED_ASSERT (geom != NULL);

       if (!ped_device_open (geom->dev))
               goto error;

       PedFileSystemType *type = ped_file_system_probe (geom);
       if (!type) {
               ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
                                    _("Could not detect file system."));
               goto error_close_dev;
       }

       open_fn_t open_f = open_fn (type->name);
       if (open_f == NULL) {
	   ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
				_("resizing %s file systems is not supported"),
				type->name);
	   goto error_close_dev;
       }

       PedGeometry *probed_geom = ped_file_system_probe_specific (type, geom);
       if (!probed_geom)
               goto error_close_dev;
       if (!ped_geometry_test_inside (geom, probed_geom)) {
               if (ped_exception_throw (
                       PED_EXCEPTION_ERROR,
                       PED_EXCEPTION_IGNORE_CANCEL,
                       _("The file system is bigger than its volume!"))
                               != PED_EXCEPTION_IGNORE)
                       goto error_destroy_probed_geom;
       }

       PedFileSystem *fs = (*open_f) (probed_geom);
       if (!fs)
               goto error_destroy_probed_geom;
       ped_geometry_destroy (probed_geom);
       fs->type = type;
       return fs;

error_destroy_probed_geom:
       ped_geometry_destroy (probed_geom);
error_close_dev:
       ped_device_close (geom->dev);
error:
       return NULL;
}
Beispiel #4
0
/**
 * This function erases all file system signatures that indicate that a
 * file system occupies a given region described by \p geom.
 * After this operation ped_file_system_probe() won't detect any file system.
 *
 * \note ped_file_system_create() calls this before creating a new file system.
 *
 * \return \c 1 on success, \c 0 on failure
 */
static int
ped_file_system_clobber (PedGeometry* geom)
{
  PED_ASSERT (geom != NULL);

  if (!ped_device_open (geom->dev))
    return 0;

  /* Clear the first three and the last two sectors, albeit fewer
     when GEOM is too small.  */
  PedSector len = MIN (geom->length, geom->dev->length);

  int ok = (len <= 5
	    ? ptt_geom_clear_sectors (geom, 0, len)
	    : (ptt_geom_clear_sectors (geom, 0, 3)
	       && ptt_geom_clear_sectors (geom, geom->dev->length - 2, 2)));

  ped_device_close (geom->dev);
  return !!ok;
}
Beispiel #5
0
PyObject *py_ped_device_open(PyObject *s, PyObject *args) {
    int ret = -1;
    PedDevice *device = NULL;

    device = _ped_Device2PedDevice(s);
    if (device == NULL) {
        return NULL;
    }

    if (device->external_mode) {
        PyErr_Format(IOException, "Device %s is already open for external access.", device->path);
        return NULL;
    }

    ret = ped_device_open(device);
    if (ret == 0) {
        if (partedExnRaised) {
            partedExnRaised = 0;

            if (!PyErr_ExceptionMatches(PartedException) &&
                !PyErr_ExceptionMatches(PyExc_NotImplementedError))
                PyErr_SetString(IOException, partedExnMessage);
        }
        else
            PyErr_Format(IOException, "Could not open device %s", device->path);

        return NULL;
    }

    ((_ped_Device *) s)->open_count = device->open_count;

    if (ret) {
        Py_RETURN_TRUE;
    } else {
        Py_RETURN_FALSE;
    }
}
Beispiel #6
0
int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
{
	/* Populate this struct, then assign it to overall array of structs. */
	nwipe_context_t* next_device;

        /* Try opening the device to see if it's valid. Close on completion. */
        if (!ped_device_open(dev))
                return 0;
        ped_device_close(dev);
        
        /* New device, reallocate memory for additional struct pointer */
        *c = realloc (*c, (dcount+1) * sizeof(nwipe_context_t *));
        
        next_device = malloc (sizeof(nwipe_context_t)); 

        /* Check the allocation. */
        if( ! next_device )
        {
                nwipe_perror( errno, __FUNCTION__, "malloc" );
                nwipe_log( NWIPE_LOG_FATAL, "Unable to create the array of enumeration contexts." );
                return 0;
        }

        /* Zero the allocation. */
        memset( next_device , 0, sizeof( nwipe_context_t ) );

        /* Get device information */
        next_device->label = dev->model;
        next_device->device_name = dev->path;
        next_device->device_size = dev->length * dev->sector_size;
        /* Attempt to get serial number of device. */
        ioctl(next_device->device_fd, HDIO_GET_IDENTITY, &next_device->identity);

        (*c)[dcount] = next_device;
        
        return 1;
}
Beispiel #7
0
/* Return a new store in STORE which contains a remap store of partition
   PART from the contents of SOURCE; SOURCE is consumed.  */
error_t
store_part_create (struct store *source, int index, int flags,
		   struct store **store)
{
  static pthread_mutex_t parted_lock = PTHREAD_MUTEX_INITIALIZER;
  static int version_check;

  error_t err = 0;
  PedDevice *dev;
  PedDisk *disk;
  PedPartition *part;
  struct store_run run;

  if ((source->block_size < PED_SECTOR_SIZE
       && PED_SECTOR_SIZE % source->block_size != 0)
      || (source->block_size > PED_SECTOR_SIZE
	  && source->block_size % PED_SECTOR_SIZE != 0))
    return EINVAL;

  pthread_mutex_lock (&parted_lock);

  /* Since Parted provides no source-level information about
     version compatibility, we have to check at run time.  */
  if (version_check == 0)
    {
      const char *version = ped_get_version ();
      version_check = -1;
      if (version == 0)
	error (0, 0, "cannot get version of Parted library!");
      else if (strverscmp (version, NEED_PARTED_VERSION) < 0)
	error (0, 0, "Parted library version %s older than needed %s",
	       version, NEED_PARTED_VERSION);
      else
	version_check = 1;
    }
  if (version_check <= 0)
    {
      error (0, 0, "the `part' store type is not available");
      pthread_mutex_unlock (&parted_lock);
      return ENOTSUP;
    }

  ped_exception_fetch_all ();

  dev = ped_device_new_from_store (source);
  if (! dev)
    {
      ped_exception_catch ();
      err = EIO;
      goto out;
    }

  assert (ped_device_open (dev) != 0);

  disk = ped_disk_new (dev);
  if (! disk)
    {
      ped_exception_catch ();
      err = EIO;
      goto out_with_dev;
    }

  for (part = ped_disk_next_partition (disk, NULL); part;
       part = ped_disk_next_partition (disk, part))
    {
      if (part->type != PED_PARTITION_LOGICAL
	  && part->type != 0 /* PED_PARTITION_PRIMARY */)
	continue;

      assert (part->num);
      if (part->num == index)
        break;
    }

  if (! part)
    {
      err = EIO;
      goto out_with_disk;
    }

  if (source->block_size == PED_SECTOR_SIZE)
    {
      run.start = part->geom.start;
      run.length = part->geom.length;
    }
  else if (source->block_size < PED_SECTOR_SIZE)
    {
      run.start = part->geom.start * (PED_SECTOR_SIZE / source->block_size);
      run.length = part->geom.length * (PED_SECTOR_SIZE / source->block_size);
    }
  else
    /* source->block_size > PED_SECTOR_SIZE */
    {
      run.start = part->geom.start * PED_SECTOR_SIZE;
      if (run.start % source->block_size != 0)
	err = EIO;
      else
	{
	  run.start /= source->block_size;
          run.length = part->geom.length * PED_SECTOR_SIZE;
	  if (run.length % source->block_size != 0)
	    err = EIO;
	  else
	    run.length /= source->block_size;
	}
    }

out_with_disk:
  assert (ped_device_close (dev) != 0);
  ped_disk_destroy (disk);
out_with_dev:
  ped_device_destroy (dev);
out:
  ped_exception_leave_all ();
  pthread_mutex_unlock (&parted_lock);

  if (! err)
    err = store_remap (source, &run, 1, store);

  return err;
}
Beispiel #8
0
/** Opens the Device
	@return true if the Device could be successfully opened
*/
bool CopySourceDevice::open()
{
	m_PedDevice = ped_device_get(device().deviceNode().toAscii());
	return m_PedDevice != NULL && ped_device_open(m_PedDevice);
}
void MParted::MParted_Core::scan(MParted::Devices & devices) {
    QMutexLocker locker(&mutex);

    // Clean up first
    devices.clear();

    // Initialise
    QStringList devicePaths;
    ped_device_probe_all();

    pedDevice = NULL;
    while ((pedDevice = ped_device_get_next(pedDevice))) {
        // Only add this device if we can read the first sector (which means it's a real device)
        char * buf = static_cast<char *>(malloc(pedDevice->sector_size));
        if (buf) {
            // Confirming device
            if (ped_device_open(pedDevice)) {
                //Devices with sector sizes of 512 bytes and higher are supported
                if (ped_device_read(pedDevice, buf, 0, 1))
                    devicePaths.append(Utils::charToString(pedDevice->path));

                ped_device_close(pedDevice) ;
            }
            free(buf);
        }
    }

    closeDeviceAndDisk();

    // Sort list, remove duplicates and empty entries
    devicePaths.removeDuplicates();
    devicePaths.removeAll("");
    devicePaths.sort();




    for (int i = 0; i < devicePaths.size(); i++) {
        const QString devicePath = devicePaths.at(i);

        // Open device and disk
        if (!openDeviceAndDisk(devicePath, false))
            continue;

        // Add to list and save pointer
        devices.append(MParted::Device());
        MParted::Device &device = devices.last();

        //device info..
        device.path = devicePath;
        device.model 	=	Utils::charToString(pedDevice->model);
        device.length 	=	pedDevice->length;
        device.sector_size	=	pedDevice->sector_size;
        device.heads 	=	pedDevice->bios_geom.heads;
        device.sectors 	=	pedDevice->bios_geom.sectors;
        device.cylinders	=	pedDevice->bios_geom.cylinders;
        device.cylsize 	=	device.heads * device.sectors;
        device.removable = isDeviceRemovable(device);


        //make sure cylsize is at least 1 MiB
        if (device.cylsize < (MEBIBYTE / device.sector_size))
            device.cylsize = (MEBIBYTE / device.sector_size);

        //normal harddisk
        if (pedDisk) {
            device.unkownPartitionTable = false;
            device.diskType =	Utils::charToString(pedDisk->type->name);
            device.maxPrimaryPartitions = ped_disk_get_max_primary_partition_count(pedDisk);

            // Scan partitions
            scanDevicePartitions(device);
        }
        //harddisk without disklabel
        else {
            device.unkownPartitionTable = true;
            device.diskType = QObject::tr("unrecognized");
            device.maxPrimaryPartitions = -1;
        }

        // Clean up
        closeDeviceAndDisk();
    }
}
MParted::FILESYSTEM MParted::MParted_Core::getFilesystem(PedPartition *pedPartition) {
    char magic1[16] = "";
    char magic2[16] = "";

    //Check for LUKS encryption prior to libparted file system detection.
    //  Otherwise encrypted file systems such as ext3 will be detected by
    //  libparted as 'ext3'.

    //LUKS encryption
    char * buf = static_cast<char *>( malloc( pedDevice ->sector_size ) ) ;
    if ( buf ) {
        ped_device_open( pedDevice );
        ped_geometry_read( & pedPartition ->geom, buf, 0, 1 ) ;
        memcpy(magic1, buf+0, 6) ;  //set binary magic data
        ped_device_close( pedDevice );
        free( buf ) ;

        if (0 == memcmp(magic1, "LUKS\xBA\xBE", 6))
            return MParted::FS_LUKS;
    }

    QString fs_type = "" ;

    //Standard libparted file system detection
    if (pedPartition && pedPartition->fs_type)
        fs_type = pedPartition ->fs_type ->name ;

    if (!fs_type.isEmpty()) {
        if ( fs_type == "extended" )
            return MParted::FS_EXTENDED ;
        else if ( fs_type == "btrfs" )
            return MParted::FS_BTRFS ;
        else if ( fs_type == "exfat" )
            return MParted::FS_EXFAT ;
        else if ( fs_type == "ext2" )
            return MParted::FS_EXT2 ;
        else if ( fs_type == "ext3" )
            return MParted::FS_EXT3 ;
        else if ( fs_type == "ext4" ||
                  fs_type == "ext4dev" )
            return MParted::FS_EXT4 ;
        else if ( fs_type == "linux-swap" ||
                  fs_type == "linux-swap(v1)" ||
                  fs_type == "linux-swap(new)" ||
                  fs_type == "linux-swap(v0)" ||
                  fs_type == "linux-swap(old)" ||
                  fs_type == "swap" )
            return MParted::FS_LINUX_SWAP ;
        else if ( fs_type == "LVM2_member" )
            return MParted::FS_LVM2_PV ;
        else if ( fs_type == "fat16" )
            return MParted::FS_FAT16 ;
        else if ( fs_type == "fat32" )
            return MParted::FS_FAT32 ;
        else if ( fs_type == "nilfs2" )
            return MParted::FS_NILFS2 ;
        else if ( fs_type == "ntfs" )
            return MParted::FS_NTFS ;
        else if ( fs_type == "reiserfs" )
            return MParted::FS_REISERFS ;
        else if ( fs_type == "xfs" )
            return MParted::FS_XFS ;
        else if ( fs_type == "jfs" )
            return MParted::FS_JFS ;
        else if ( fs_type == "hfs" )
            return MParted::FS_HFS ;
        else if ( fs_type == "hfs+" ||
                  fs_type == "hfsplus" )
            return MParted::FS_HFSPLUS ;
        else if ( fs_type == "ufs" )
            return MParted::FS_UFS ;
    }



    //other file systems libparted couldn't detect (i've send patches for these file systems to the parted guys)
    // - no patches sent to parted for lvm2, or luks

    //reiser4
    buf = static_cast<char *>( malloc( pedDevice ->sector_size ) ) ;
    if ( buf )
    {
        ped_device_open( pedDevice );
        ped_geometry_read( & pedPartition ->geom
                         , buf
                         , (65536 / pedDevice ->sector_size)
                         , 1
                         ) ;
        memcpy(magic1, buf+0, 7) ; //set binary magic data
        ped_device_close( pedDevice );
        free( buf ) ;

        if ( 0 == memcmp( magic1, "ReIsEr4", 7 ) )
            return MParted::FS_REISER4 ;
    }

    //lvm2
    //NOTE: lvm2 is not a file system but we do wish to recognize the Physical Volume
    buf = static_cast<char *>( malloc( pedDevice ->sector_size ) ) ;
    if ( buf )
    {
        ped_device_open( pedDevice );
        if ( pedDevice ->sector_size == 512 )
        {
            ped_geometry_read( & pedPartition ->geom, buf, 1, 1 ) ;
            memcpy(magic1, buf+ 0, 8) ; // set binary magic data
            memcpy(magic2, buf+24, 4) ; // set binary magic data
        }
        else
        {
            ped_geometry_read( & pedPartition ->geom, buf, 0, 1 ) ;
            memcpy(magic1, buf+ 0+512, 8) ; // set binary magic data
            memcpy(magic2, buf+24+512, 4) ; // set binary magic data
        }
        ped_device_close( pedDevice );
        free( buf ) ;

        if (    0 == memcmp( magic1, "LABELONE", 8 )
             && 0 == memcmp( magic2, "LVM2", 4 ) )
        {
            return MParted::FS_LVM2_PV ;
        }
    }

    //btrfs
    const Sector BTRFS_SUPER_INFO_SIZE   = 4096 ;
    const Sector BTRFS_SUPER_INFO_OFFSET = (64 * 1024) ;
    const char* const BTRFS_SIGNATURE  = "_BHRfS_M" ;

    char    buf_btrfs[BTRFS_SUPER_INFO_SIZE] ;

    ped_device_open( pedDevice ) ;
    ped_geometry_read( & pedPartition ->geom
                     , buf_btrfs
                     , (BTRFS_SUPER_INFO_OFFSET / pedDevice ->sector_size)
                     , (BTRFS_SUPER_INFO_SIZE / pedDevice ->sector_size)
                     ) ;
    memcpy(magic1, buf_btrfs+64, strlen(BTRFS_SIGNATURE) ) ;  //set binary magic data
    ped_device_close( pedDevice ) ;

    if ( 0 == memcmp( magic1, BTRFS_SIGNATURE, strlen(BTRFS_SIGNATURE) ) )
    {
        return MParted::FS_BTRFS ;
    }


    //no file system found....
    return MParted::FS_UNKNOWN ;
}
Beispiel #11
0
int
main (int argc, char **argv)
{
	set_program_name (argv[0]);

	PedSector start = 0, len = 0;
	PedGeometry geom, new_geom;
	PedDevice *dev;
	PedFileSystem *fs;
	PedTimer *g_timer = NULL;

	if (argc != 2 && argc != 4) {
		fprintf(stderr, "usage: %s <device>\n"
				"       %s <device> <start> <length>\n",
				argv[0], argv[0]);
		return 1;
	}

	dev = ped_device_get(argv[1]);
	if (!dev) {
		fprintf(stderr, "cannot create device %s\n", argv[1]);
		return 1;
	}

	if (!ped_device_open(dev)) {
		fprintf(stderr, "cannot open device %s\n", argv[1]);
		return 1;
	}

	if (!ped_geometry_init(&geom, dev, 0, dev->length)) {
		fprintf(stderr, "cannot initialize geometry\n");
		return 1;
	}

	if (argc > 2) {
		start = strtoll(argv[2], NULL, 0);
		len = strtoll(argv[3], NULL, 0);
	} else {
		start = 0;
		len = dev->length;
	}

	if (!ped_geometry_init(&new_geom, dev, start, len)) {
		fprintf(stderr, "cannot initialize new geometry\n");
		return 1;
	}

	fs = ped_file_system_open(&geom);
	if (!fs) {
		fprintf(stderr, "cannot read fs\n");
		return 1;
	}

	if (!ped_file_system_resize(fs, &new_geom, g_timer)) {
		fprintf(stderr, "cannot resize filesystem\n");
		return 1;
	}

	ped_file_system_close(fs);
	return 0;
}
Beispiel #12
0
bool Device::open() {
    return ped_device_open(dev);
}