|
Packit Service |
158247 |
/*
|
|
Packit Service |
158247 |
* Copyright (C) 2016 Red Hat, Inc.
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* This library is free software; you can redistribute it and/or
|
|
Packit Service |
158247 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit Service |
158247 |
* License as published by the Free Software Foundation; either
|
|
Packit Service |
158247 |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* This library is distributed in the hope that it will be useful,
|
|
Packit Service |
158247 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
158247 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
158247 |
* Lesser General Public License for more details.
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit Service |
158247 |
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Author: Vratislav Podzimek <vpodzime@redhat.com>
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
#include <string.h>
|
|
Packit Service |
158247 |
#include <parted/parted.h>
|
|
Packit Service |
158247 |
#include <ctype.h>
|
|
Packit Service |
158247 |
#include <stdlib.h>
|
|
Packit Service |
158247 |
#include <math.h>
|
|
Packit Service |
158247 |
#include <inttypes.h>
|
|
Packit Service |
158247 |
#include <unistd.h>
|
|
Packit Service |
158247 |
#include <sys/file.h>
|
|
Packit Service |
158247 |
#include <fcntl.h>
|
|
Packit Service |
158247 |
#include <sys/ioctl.h>
|
|
Packit Service |
158247 |
#include <linux/fs.h>
|
|
Packit Service |
158247 |
#include <blockdev/utils.h>
|
|
Packit Service |
158247 |
#include <part_err.h>
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
#include "part.h"
|
|
Packit Service |
158247 |
#include "check_deps.h"
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* SECTION: part
|
|
Packit Service |
158247 |
* @short_description: plugin for operations with partition tables
|
|
Packit Service |
158247 |
* @title: Part
|
|
Packit Service |
158247 |
* @include: part.h
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* A plugin for operations with partition tables. Currently supported table
|
|
Packit Service |
158247 |
* (disk label) types are MBR and GPT. See the functions below to get an
|
|
Packit Service |
158247 |
* overview of which operations are supported. If there's anything missing,
|
|
Packit Service |
158247 |
* please don't hesitate to report it as this plugin (just like all the others)
|
|
Packit Service |
158247 |
* is subject to future development and enhancements.
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* This particular implementation of the part plugin uses libparted for
|
|
Packit Service |
158247 |
* manipulations of both the MBR and GPT disk label types together with the
|
|
Packit Service |
158247 |
* sgdisk utility for some extra GPT-specific features libparted doesn't
|
|
Packit Service |
158247 |
* support. In the future, there's likely to be another implementation of this
|
|
Packit Service |
158247 |
* plugin based on libfdisk which provides full support for both MBR and GPT
|
|
Packit Service |
158247 |
* tables (and possibly some others).
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_error_quark: (skip)
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
GQuark bd_part_error_quark (void)
|
|
Packit Service |
158247 |
{
|
|
Packit Service |
158247 |
return g_quark_from_static_string ("g-bd-part-error-quark");
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
BDPartSpec* bd_part_spec_copy (BDPartSpec *data) {
|
|
Packit Service |
158247 |
if (data == NULL)
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
BDPartSpec *ret = g_new0 (BDPartSpec, 1);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ret->path = g_strdup (data->path);
|
|
Packit Service |
158247 |
ret->name = g_strdup (data->name);
|
|
Packit Service |
158247 |
ret->type_guid = g_strdup (data->type_guid);
|
|
Packit Service |
158247 |
ret->type = data->type;
|
|
Packit Service |
158247 |
ret->start = data->start;
|
|
Packit Service |
158247 |
ret->size = data->size;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return ret;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
void bd_part_spec_free (BDPartSpec *data) {
|
|
Packit Service |
158247 |
if (data == NULL)
|
|
Packit Service |
158247 |
return;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
g_free (data->path);
|
|
Packit Service |
158247 |
g_free (data->name);
|
|
Packit Service |
158247 |
g_free (data->type_guid);
|
|
Packit Service |
158247 |
g_free (data);
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
BDPartDiskSpec* bd_part_disk_spec_copy (BDPartDiskSpec *data) {
|
|
Packit Service |
158247 |
if (data == NULL)
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
BDPartDiskSpec *ret = g_new0 (BDPartDiskSpec, 1);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ret->path = g_strdup (data->path);
|
|
Packit Service |
158247 |
ret->table_type = data->table_type;
|
|
Packit Service |
158247 |
ret->size = data->size;
|
|
Packit Service |
158247 |
ret->sector_size = data->sector_size;
|
|
Packit Service |
158247 |
ret->flags = data->flags;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return ret;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
void bd_part_disk_spec_free (BDPartDiskSpec *data) {
|
|
Packit Service |
158247 |
if (data == NULL)
|
|
Packit Service |
158247 |
return;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
g_free (data->path);
|
|
Packit Service |
158247 |
g_free (data);
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* set_parted_error: (skip)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Set error from the parted error stored in 'error_msg'. In case there is none,
|
|
Packit Service |
158247 |
* the error is set up with an empty string. Otherwise it is set up with the
|
|
Packit Service |
158247 |
* parted's error message and is a subject to later g_prefix_error() call.
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: whether there was some message from parted or not
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
static gboolean set_parted_error (GError **error, BDPartError type) {
|
|
Packit Service |
158247 |
gchar *error_msg = NULL;
|
|
Packit Service |
158247 |
error_msg = bd_get_error_msg ();
|
|
Packit Service |
158247 |
if (error_msg) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, type,
|
|
Packit Service |
158247 |
" (%s)", error_msg);
|
|
Packit Service |
158247 |
g_free (error_msg);
|
|
Packit Service |
158247 |
error_msg = NULL;
|
|
Packit Service |
158247 |
return TRUE;
|
|
Packit Service |
158247 |
} else {
|
|
Packit Service |
158247 |
g_set_error_literal (error, BD_PART_ERROR, type, "");
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
static volatile guint avail_deps = 0;
|
|
Packit Service |
158247 |
static GMutex deps_check_lock;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
#define DEPS_SGDISK 0
|
|
Packit Service |
158247 |
#define DEPS_SGDISK_MASK (1 << DEPS_SGDISK)
|
|
Packit Service |
158247 |
#define DEPS_SFDISK 1
|
|
Packit Service |
158247 |
#define DEPS_SFDISK_MASK (1 << DEPS_SFDISK)
|
|
Packit Service |
158247 |
#define DEPS_LAST 2
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
static const UtilDep deps[DEPS_LAST] = {
|
|
Packit Service |
158247 |
{"sgdisk", "0.8.6", NULL, "GPT fdisk \\(sgdisk\\) version ([\\d\\.]+)"},
|
|
Packit Service |
158247 |
{"sfdisk", NULL, NULL, NULL},
|
|
Packit Service |
158247 |
};
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_check_deps:
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: whether the plugin's runtime dependencies are satisfied or not
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Function checking plugin's runtime dependencies.
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
gboolean bd_part_check_deps (void) {
|
|
Packit Service |
158247 |
GError *error = NULL;
|
|
Packit Service |
158247 |
guint i = 0;
|
|
Packit Service |
158247 |
gboolean status = FALSE;
|
|
Packit Service |
158247 |
gboolean ret = TRUE;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
for (i=0; i < DEPS_LAST; i++) {
|
|
Packit Service |
158247 |
status = bd_utils_check_util_version (deps[i].name, deps[i].version,
|
|
Packit Service |
158247 |
deps[i].ver_arg, deps[i].ver_regexp, &error);
|
|
Packit Service |
158247 |
if (!status)
|
|
Packit Service |
158247 |
g_warning ("%s", error->message);
|
|
Packit Service |
158247 |
else
|
|
Packit Service |
158247 |
g_atomic_int_or (&avail_deps, 1 << i);
|
|
Packit Service |
158247 |
g_clear_error (&error);
|
|
Packit Service |
158247 |
ret = ret && status;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (!ret)
|
|
Packit Service |
158247 |
g_warning("Cannot load the part plugin");
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return ret;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_init:
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Initializes the plugin. **This function is called automatically by the
|
|
Packit Service |
158247 |
* library's initialization functions.**
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
gboolean bd_part_init (void) {
|
|
Packit Service |
158247 |
ped_exception_set_handler ((PedExceptionHandler*) bd_exc_handler);
|
|
Packit Service |
158247 |
return TRUE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_close:
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Cleans up after the plugin. **This function is called automatically by the
|
|
Packit Service |
158247 |
* library's functions that unload it.**
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
void bd_part_close (void) {
|
|
Packit Service |
158247 |
ped_exception_set_handler (NULL);
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_is_tech_avail:
|
|
Packit Service |
158247 |
* @tech: the queried tech
|
|
Packit Service |
158247 |
* @mode: a bit mask of queried modes of operation (#BDPartTechMode) for @tech
|
|
Packit Service |
158247 |
* @error: (out): place to store error (details about why the @tech-@mode combination is not available)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: whether the @tech-@mode combination is available -- supported by the
|
|
Packit Service |
158247 |
* plugin implementation and having all the runtime dependencies available
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
gboolean bd_part_is_tech_avail (BDPartTech tech, guint64 mode, GError **error) {
|
|
Packit Service |
158247 |
switch (tech) {
|
|
Packit Service |
158247 |
case BD_PART_TECH_MBR:
|
|
Packit Service |
158247 |
/* all MBR-mode combinations are supported by this implementation of the
|
|
Packit Service |
158247 |
* plugin, nothing extra is needed */
|
|
Packit Service |
158247 |
return TRUE;
|
|
Packit Service |
158247 |
case BD_PART_TECH_GPT:
|
|
Packit Service |
158247 |
if (mode & (BD_PART_TECH_MODE_MODIFY_PART|BD_PART_TECH_MODE_QUERY_PART))
|
|
Packit Service |
158247 |
return check_deps (&avail_deps, DEPS_SGDISK_MASK|DEPS_SFDISK_MASK,
|
|
Packit Service |
158247 |
deps, DEPS_LAST, &deps_check_lock, error);
|
|
Packit Service |
158247 |
else
|
|
Packit Service |
158247 |
return TRUE;
|
|
Packit Service |
158247 |
default:
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_TECH_UNAVAIL, "Unknown technology");
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
static const gchar *table_type_str[BD_PART_TABLE_UNDEF] = {"msdos", "gpt"};
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
static gboolean disk_commit (PedDisk *disk, const gchar *path, GError **error) {
|
|
Packit Service |
158247 |
gint ret = 0;
|
|
Packit Service |
158247 |
gint dev_fd = 0;
|
|
Packit Service |
158247 |
guint num_tries = 1;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* XXX: try to grab a lock for the device so that udev doesn't step in
|
|
Packit Service |
158247 |
between the two operations we need to perform (see below) with its
|
|
Packit Service |
158247 |
BLKRRPART ioctl() call which makes the device busy */
|
|
Packit Service |
158247 |
dev_fd = open (disk->dev->path, O_RDONLY|O_CLOEXEC);
|
|
Packit Service |
158247 |
if (dev_fd >= 0) {
|
|
Packit Service |
158247 |
ret = flock (dev_fd, LOCK_SH|LOCK_NB);
|
|
Packit Service |
158247 |
while ((ret != 0) && (num_tries <= 5)) {
|
|
Packit Service |
158247 |
g_usleep (100 * 1000); /* microseconds */
|
|
Packit Service |
158247 |
ret = flock (dev_fd, LOCK_SH|LOCK_NB);
|
|
Packit Service |
158247 |
num_tries++;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
/* Just continue even in case we don't get the lock, there's still a
|
|
Packit Service |
158247 |
chance things will just work. If not, an error will be reported
|
|
Packit Service |
158247 |
anyway with no harm. */
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* XXX: Sometimes it happens that when we try to commit the partition table
|
|
Packit Service |
158247 |
to disk below, libparted kills the process due to the
|
|
Packit Service |
158247 |
assert(disk->dev->open_count > 0). This looks like a bug to me, but we
|
|
Packit Service |
158247 |
have no reproducer for it. Let's just try to (re)open the device in such
|
|
Packit Service |
158247 |
cases. It is later closed by the ped_device_destroy() call. */
|
|
Packit Service |
158247 |
if (disk->dev->open_count <= 0)
|
|
Packit Service |
158247 |
ped_device_open (disk->dev);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ret = ped_disk_commit_to_dev (disk);
|
|
Packit Service |
158247 |
if (ret == 0) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to commit changes to device '%s'", path);
|
|
Packit Service |
158247 |
if (dev_fd >= 0)
|
|
Packit Service |
158247 |
close (dev_fd);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ret = ped_disk_commit_to_os (disk);
|
|
Packit Service |
158247 |
if (ret == 0) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to inform OS about changes on the '%s' device", path);
|
|
Packit Service |
158247 |
if (dev_fd >= 0)
|
|
Packit Service |
158247 |
close (dev_fd);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (dev_fd >= 0)
|
|
Packit Service |
158247 |
close (dev_fd);
|
|
Packit Service |
158247 |
return TRUE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_create_table:
|
|
Packit Service |
158247 |
* @disk: path of the disk block device to create partition table on
|
|
Packit Service |
158247 |
* @type: type of the partition table to create
|
|
Packit Service |
158247 |
* @ignore_existing: whether to ignore/overwrite the existing table or not
|
|
Packit Service |
158247 |
* (reports an error if %FALSE and there's some table on @disk)
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: whether the partition table was successfully created or not
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: %BD_PART_TECH_MODE_CREATE_TABLE + the tech according to @type
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
gboolean bd_part_create_table (const gchar *disk, BDPartTableType type, gboolean ignore_existing, GError **error) {
|
|
Packit Service |
158247 |
PedDevice *dev = NULL;
|
|
Packit Service |
158247 |
PedDisk *ped_disk = NULL;
|
|
Packit Service |
158247 |
PedDiskType *disk_type = NULL;
|
|
Packit Service |
158247 |
gboolean ret = FALSE;
|
|
Packit Service |
158247 |
guint64 progress_id = 0;
|
|
Packit Service |
158247 |
gchar *msg = NULL;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
msg = g_strdup_printf ("Starting creation of a new partition table on '%s'", disk);
|
|
Packit Service |
158247 |
progress_id = bd_utils_report_started (msg);
|
|
Packit Service |
158247 |
g_free (msg);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
dev = ped_device_get (disk);
|
|
Packit Service |
158247 |
if (!dev) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_INVAL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Device '%s' invalid or not existing", disk);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (!ignore_existing) {
|
|
Packit Service |
158247 |
ped_disk = ped_disk_new (dev);
|
|
Packit Service |
158247 |
if (ped_disk) {
|
|
Packit Service |
158247 |
/* no parted error */
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_EXISTS,
|
|
Packit Service |
158247 |
"Device '%s' already contains a partition table", disk);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
disk_type = ped_disk_type_get (table_type_str[type]);
|
|
Packit Service |
158247 |
ped_disk = ped_disk_new_fresh (dev, disk_type);
|
|
Packit Service |
158247 |
if (!ped_disk) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to create a new partition table of type '%s' on device '%s'",
|
|
Packit Service |
158247 |
table_type_str[type], disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* commit changes to disk */
|
|
Packit Service |
158247 |
ret = disk_commit (ped_disk, disk, error);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, "Completed");
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* just return what we got (error may be set) */
|
|
Packit Service |
158247 |
return ret;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
static gchar* get_part_type_guid_and_gpt_flags (const gchar *device, int part_num, guint64 *flags, GError **error) {
|
|
Packit Service |
158247 |
const gchar *args[4] = {"sgdisk", NULL, device, NULL};
|
|
Packit Service |
158247 |
gchar *output = NULL;
|
|
Packit Service |
158247 |
gchar **lines = NULL;
|
|
Packit Service |
158247 |
gchar **line_p = NULL;
|
|
Packit Service |
158247 |
gchar *guid_line = NULL;
|
|
Packit Service |
158247 |
gchar *attrs_line = NULL;
|
|
Packit Service |
158247 |
gchar *guid_start = NULL;
|
|
Packit Service |
158247 |
gchar *attrs_start = NULL;
|
|
Packit Service |
158247 |
guint64 flags_mask = 0;
|
|
Packit Service |
158247 |
gboolean success = FALSE;
|
|
Packit Service |
158247 |
gchar *space = NULL;
|
|
Packit Service |
158247 |
gchar *ret = NULL;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (!check_deps (&avail_deps, DEPS_SGDISK_MASK, deps, DEPS_LAST, &deps_check_lock, error))
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
args[1] = g_strdup_printf ("-i%d", part_num);
|
|
Packit Service |
158247 |
success = bd_utils_exec_and_capture_output (args, NULL, &output, error);
|
|
Packit Service |
158247 |
g_free ((gchar *) args[1]);
|
|
Packit Service |
158247 |
if (!success)
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
lines = g_strsplit (output, "\n", 0);
|
|
Packit Service |
158247 |
g_free (output);
|
|
Packit Service |
158247 |
for (line_p=lines; *line_p && (!guid_line || !attrs_line); line_p++) {
|
|
Packit Service |
158247 |
if (g_str_has_prefix (*line_p, "Partition GUID code: "))
|
|
Packit Service |
158247 |
guid_line = *line_p;
|
|
Packit Service |
158247 |
else if (g_str_has_prefix (*line_p, "Attribute flags: "))
|
|
Packit Service |
158247 |
attrs_line = *line_p;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
if (!guid_line && !attrs_line) {
|
|
Packit Service |
158247 |
g_strfreev (lines);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (guid_line) {
|
|
Packit Service |
158247 |
guid_start = guid_line + 21; /* strlen("Partition GUID...") */
|
|
Packit Service |
158247 |
space = strchr (guid_start, ' '); /* find the first space after the GUID */
|
|
Packit Service |
158247 |
if (space)
|
|
Packit Service |
158247 |
*space = '\0';
|
|
Packit Service |
158247 |
ret = g_strdup (guid_start);
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (attrs_line) {
|
|
Packit Service |
158247 |
attrs_start = attrs_line + 17; /* strlen("Attribute flags: ") */
|
|
Packit Service |
158247 |
flags_mask = strtoull (attrs_start, NULL, 16);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (flags_mask & 1) /* 1 << 0 */
|
|
Packit Service |
158247 |
*flags |= BD_PART_FLAG_GPT_SYSTEM_PART;
|
|
Packit Service |
158247 |
if (flags_mask & 4) /* 1 << 2 */
|
|
Packit Service |
158247 |
*flags |= BD_PART_FLAG_LEGACY_BOOT;
|
|
Packit Service |
158247 |
if (flags_mask & 0x1000000000000000) /* 1 << 60 */
|
|
Packit Service |
158247 |
*flags |= BD_PART_FLAG_GPT_READ_ONLY;
|
|
Packit Service |
158247 |
if (flags_mask & 0x4000000000000000) /* 1 << 62 */
|
|
Packit Service |
158247 |
*flags |= BD_PART_FLAG_GPT_HIDDEN;
|
|
Packit Service |
158247 |
if (flags_mask & 0x8000000000000000) /* 1 << 63 */
|
|
Packit Service |
158247 |
*flags |= BD_PART_FLAG_GPT_NO_AUTOMOUNT;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
g_strfreev (lines);
|
|
Packit Service |
158247 |
return ret;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
static BDPartSpec* get_part_spec (PedDevice *dev, PedDisk *disk, PedPartition *part, GError **error) {
|
|
Packit Service |
158247 |
BDPartSpec *ret = NULL;
|
|
Packit Service |
158247 |
PedPartitionFlag flag = PED_PARTITION_FIRST_FLAG;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ret = g_new0 (BDPartSpec, 1);
|
|
Packit Service |
158247 |
/* the no-partition "partitions" have num equal to -1 which never really
|
|
Packit Service |
158247 |
creates a valid block device path, so let's just not set path to
|
|
Packit Service |
158247 |
nonsense */
|
|
Packit Service |
158247 |
if (part->num != -1) {
|
|
Packit Service |
158247 |
if (isdigit (dev->path[strlen(dev->path) - 1]))
|
|
Packit Service |
158247 |
ret->path = g_strdup_printf ("%sp%d", dev->path, part->num);
|
|
Packit Service |
158247 |
else
|
|
Packit Service |
158247 |
ret->path = g_strdup_printf ("%s%d", dev->path, part->num);
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
if (ped_partition_is_active (part) && disk->type->features & PED_DISK_TYPE_PARTITION_NAME)
|
|
Packit Service |
158247 |
ret->name = g_strdup (ped_partition_get_name (part));
|
|
Packit Service |
158247 |
if (g_strcmp0 (disk->type->name, "gpt") == 0) {
|
|
Packit Service |
158247 |
ret->type_guid = get_part_type_guid_and_gpt_flags (dev->path, part->num, &(ret->flags), error);
|
|
Packit Service |
158247 |
if (!ret->type_guid && *error) {
|
|
Packit Service |
158247 |
bd_part_spec_free (ret);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
ret->type = (BDPartType) part->type;
|
|
Packit Service |
158247 |
ret->start = part->geom.start * dev->sector_size;
|
|
Packit Service |
158247 |
ret->size = part->geom.length * dev->sector_size;
|
|
Packit Service |
158247 |
for (flag=PED_PARTITION_FIRST_FLAG; flag
|
|
Packit Service |
158247 |
/* beware of partition types that segfault when asked for flags */
|
|
Packit Service |
158247 |
if ((part->type <= PED_PARTITION_EXTENDED) &&
|
|
Packit Service |
158247 |
ped_partition_is_flag_available (part, flag) && ped_partition_get_flag (part, flag))
|
|
Packit Service |
158247 |
/* our flags are 1s shifted to the bit determined by parted's flags
|
|
Packit Service |
158247 |
* (i.e. 1 << 3 instead of 3, etc.) */
|
|
Packit Service |
158247 |
ret->flags = ret->flags | (1 << flag);
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return ret;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_get_part_spec:
|
|
Packit Service |
158247 |
* @disk: disk to remove the partition from
|
|
Packit Service |
158247 |
* @part: partition to get spec for
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: (transfer full): spec of the @part partition from @disk or %NULL in case of error
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: %BD_PART_TECH_MODE_QUERY_PART + the tech according to the partition table type
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
BDPartSpec* bd_part_get_part_spec (const gchar *disk, const gchar *part, GError **error) {
|
|
Packit Service |
158247 |
PedDevice *dev = NULL;
|
|
Packit Service |
158247 |
PedDisk *ped_disk = NULL;
|
|
Packit Service |
158247 |
PedPartition *ped_part = NULL;
|
|
Packit Service |
158247 |
const gchar *part_num_str = NULL;
|
|
Packit Service |
158247 |
gint part_num = 0;
|
|
Packit Service |
158247 |
BDPartSpec *ret = NULL;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (!part || (part && (*part == '\0'))) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition path given: '%s'", part);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
dev = ped_device_get (disk);
|
|
Packit Service |
158247 |
if (!dev) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_INVAL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Device '%s' invalid or not existing", disk);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_disk = ped_disk_new (dev);
|
|
Packit Service |
158247 |
if (!ped_disk) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to read partition table on device '%s'", disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
part_num_str = part + (strlen (part) - 1);
|
|
Packit Service |
158247 |
while (isdigit (*part_num_str) || (*part_num_str == '-')) {
|
|
Packit Service |
158247 |
part_num_str--;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
part_num_str++;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
part_num = atoi (part_num_str);
|
|
Packit Service |
158247 |
if (part_num == 0) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition path given: '%s'. Cannot extract partition number", part);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_part = ped_disk_get_partition (ped_disk, part_num);
|
|
Packit Service |
158247 |
if (!ped_part) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to get partition '%d' on device '%s'", part_num, disk);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ret = get_part_spec (dev, ped_disk, ped_part, error);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* the partition gets destroyed together with the disk */
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return ret;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_get_part_by_pos:
|
|
Packit Service |
158247 |
* @disk: disk to remove the partition from
|
|
Packit Service |
158247 |
* @position: position (in bytes) determining the partition
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: (transfer full): spec of the partition from @disk spanning over the @position or %NULL if no such
|
|
Packit Service |
158247 |
* partition exists or in case of error (@error is set)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: %BD_PART_TECH_MODE_QUERY_PART + the tech according to the partition table type
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
BDPartSpec* bd_part_get_part_by_pos (const gchar *disk, guint64 position, GError **error) {
|
|
Packit Service |
158247 |
PedDevice *dev = NULL;
|
|
Packit Service |
158247 |
PedDisk *ped_disk = NULL;
|
|
Packit Service |
158247 |
PedPartition *ped_part = NULL;
|
|
Packit Service |
158247 |
BDPartSpec *ret = NULL;
|
|
Packit Service |
158247 |
PedSector sector = 0;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
dev = ped_device_get (disk);
|
|
Packit Service |
158247 |
if (!dev) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_INVAL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Device '%s' invalid or not existing", disk);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_disk = ped_disk_new (dev);
|
|
Packit Service |
158247 |
if (!ped_disk) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to read partition table on device '%s'", disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
sector = (PedSector) (position / dev->sector_size);
|
|
Packit Service |
158247 |
ped_part = ped_disk_get_partition_by_sector (ped_disk, sector);
|
|
Packit Service |
158247 |
if (!ped_part) {
|
|
Packit Service |
158247 |
if (set_parted_error (error, BD_PART_ERROR_FAIL))
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to get partition at position %"G_GUINT64_FORMAT" (device '%s')",
|
|
Packit Service |
158247 |
position, disk);
|
|
Packit Service |
158247 |
else
|
|
Packit Service |
158247 |
/* no such partition, but no error */
|
|
Packit Service |
158247 |
g_clear_error (error);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ret = get_part_spec (dev, ped_disk, ped_part, error);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* the partition gets destroyed together with the disk */
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return ret;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_get_disk_spec:
|
|
Packit Service |
158247 |
* @disk: disk to get information about
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: (transfer full): information about the given @disk or %NULL (in case of error)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: %BD_PART_TECH_MODE_QUERY_TABLE + the tech according to the partition table type
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
BDPartDiskSpec* bd_part_get_disk_spec (const gchar *disk, GError **error) {
|
|
Packit Service |
158247 |
PedDevice *dev = NULL;
|
|
Packit Service |
158247 |
BDPartDiskSpec *ret = NULL;
|
|
Packit Service |
158247 |
PedConstraint *constr = NULL;
|
|
Packit Service |
158247 |
PedDisk *ped_disk = NULL;
|
|
Packit Service |
158247 |
BDPartTableType type = BD_PART_TABLE_UNDEF;
|
|
Packit Service |
158247 |
gboolean found = FALSE;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
dev = ped_device_get (disk);
|
|
Packit Service |
158247 |
if (!dev) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_INVAL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Device '%s' invalid or not existing", disk);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ret = g_new0 (BDPartDiskSpec, 1);
|
|
Packit Service |
158247 |
ret->path = g_strdup (dev->path);
|
|
Packit Service |
158247 |
ret->sector_size = (guint64) dev->sector_size;
|
|
Packit Service |
158247 |
constr = ped_device_get_constraint (dev);
|
|
Packit Service |
158247 |
ret->size = (constr->max_size - 1) * dev->sector_size;
|
|
Packit Service |
158247 |
ped_constraint_destroy (constr);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_disk = ped_disk_new (dev);
|
|
Packit Service |
158247 |
if (ped_disk) {
|
|
Packit Service |
158247 |
for (type=BD_PART_TABLE_MSDOS; !found && type < BD_PART_TABLE_UNDEF; type++) {
|
|
Packit Service |
158247 |
if (g_strcmp0 (ped_disk->type->name, table_type_str[type]) == 0) {
|
|
Packit Service |
158247 |
ret->table_type = type;
|
|
Packit Service |
158247 |
found = TRUE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
if (!found)
|
|
Packit Service |
158247 |
ret->table_type = BD_PART_TABLE_UNDEF;
|
|
Packit Service |
158247 |
if (ped_disk_is_flag_available (ped_disk, PED_DISK_GPT_PMBR_BOOT) &&
|
|
Packit Service |
158247 |
ped_disk_get_flag (ped_disk, PED_DISK_GPT_PMBR_BOOT))
|
|
Packit Service |
158247 |
ret->flags = BD_PART_DISK_FLAG_GPT_PMBR_BOOT;
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
} else {
|
|
Packit Service |
158247 |
ret->table_type = BD_PART_TABLE_UNDEF;
|
|
Packit Service |
158247 |
ret->flags = 0;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return ret;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
static BDPartSpec** get_disk_parts (const gchar *disk, guint64 incl, guint64 excl, gboolean incl_normal, GError **error) {
|
|
Packit Service |
158247 |
PedDevice *dev = NULL;
|
|
Packit Service |
158247 |
PedDisk *ped_disk = NULL;
|
|
Packit Service |
158247 |
PedPartition *ped_part = NULL;
|
|
Packit Service |
158247 |
guint num_parts = 0;
|
|
Packit Service |
158247 |
BDPartSpec **ret = NULL;
|
|
Packit Service |
158247 |
guint i = 0;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
dev = ped_device_get (disk);
|
|
Packit Service |
158247 |
if (!dev) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_INVAL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Device '%s' invalid or not existing", disk);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_disk = ped_disk_new (dev);
|
|
Packit Service |
158247 |
if (!ped_disk) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to read partition table on device '%s'", disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* count the partitions we care about */
|
|
Packit Service |
158247 |
ped_part = ped_disk_next_partition (ped_disk, NULL);
|
|
Packit Service |
158247 |
while (ped_part) {
|
|
Packit Service |
158247 |
if (((ped_part->type & incl) && !(ped_part->type & excl)) ||
|
|
Packit Service |
158247 |
((ped_part->type == 0) && incl_normal))
|
|
Packit Service |
158247 |
num_parts++;
|
|
Packit Service |
158247 |
ped_part = ped_disk_next_partition (ped_disk, ped_part);
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ret = g_new0 (BDPartSpec*, num_parts + 1);
|
|
Packit Service |
158247 |
i = 0;
|
|
Packit Service |
158247 |
ped_part = ped_disk_next_partition (ped_disk, NULL);
|
|
Packit Service |
158247 |
while (ped_part) {
|
|
Packit Service |
158247 |
if (((ped_part->type & incl) && !(ped_part->type & excl)) ||
|
|
Packit Service |
158247 |
((ped_part->type == 0) && incl_normal))
|
|
Packit Service |
158247 |
ret[i++] = get_part_spec (dev, ped_disk, ped_part, error);
|
|
Packit Service |
158247 |
ped_part = ped_disk_next_partition (ped_disk, ped_part);
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
ret[i] = NULL;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return ret;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_get_disk_parts:
|
|
Packit Service |
158247 |
* @disk: disk to get information about partitions for
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: (transfer full) (array zero-terminated=1): specs of the partitions from @disk or %NULL in case of error
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: %BD_PART_TECH_MODE_QUERY_TABLE + the tech according to the partition table type
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
BDPartSpec** bd_part_get_disk_parts (const gchar *disk, GError **error) {
|
|
Packit Service |
158247 |
return get_disk_parts (disk, BD_PART_TYPE_NORMAL|BD_PART_TYPE_LOGICAL|BD_PART_TYPE_EXTENDED,
|
|
Packit Service |
158247 |
BD_PART_TYPE_FREESPACE|BD_PART_TYPE_METADATA|BD_PART_TYPE_PROTECTED, TRUE, error);
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_get_disk_free_regions:
|
|
Packit Service |
158247 |
* @disk: disk to get free regions for
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: (transfer full) (array zero-terminated=1): specs of the free regions from @disk or %NULL in case of error
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: %BD_PART_TECH_MODE_QUERY_TABLE + the tech according to the partition table type
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
BDPartSpec** bd_part_get_disk_free_regions (const gchar *disk, GError **error) {
|
|
Packit Service |
158247 |
return get_disk_parts (disk, BD_PART_TYPE_FREESPACE, 0, FALSE, error);
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_get_best_free_region:
|
|
Packit Service |
158247 |
* @disk: disk to get the best free region for
|
|
Packit Service |
158247 |
* @type: type of the partition that is planned to be added
|
|
Packit Service |
158247 |
* @size: size of the partition to be added
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: (transfer full): spec of the best free region on @disk for a new partition of type @type
|
|
Packit Service |
158247 |
* with the size of @size or %NULL if there is none such region or if
|
|
Packit Service |
158247 |
* there was an error (@error gets populated)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Note: For the @type %BD_PART_TYPE_NORMAL, the smallest possible space that *is not* in an extended partition
|
|
Packit Service |
158247 |
* is found. For the @type %BD_PART_TYPE_LOGICAL, the smallest possible space that *is* in an extended
|
|
Packit Service |
158247 |
* partition is found. For %BD_PART_TYPE_EXTENDED, the biggest possible space is found as long as there
|
|
Packit Service |
158247 |
* is no other extended partition (there can only be one).
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: %BD_PART_TECH_MODE_QUERY_TABLE + the tech according to the partition table type
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
BDPartSpec* bd_part_get_best_free_region (const gchar *disk, BDPartType type, guint64 size, GError **error) {
|
|
Packit Service |
158247 |
BDPartSpec **free_regs = NULL;
|
|
Packit Service |
158247 |
BDPartSpec **free_reg_p = NULL;
|
|
Packit Service |
158247 |
BDPartSpec *ret = NULL;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
free_regs = bd_part_get_disk_free_regions (disk, error);
|
|
Packit Service |
158247 |
if (!free_regs)
|
|
Packit Service |
158247 |
/* error should be populated */
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
if (!(*free_regs)) {
|
|
Packit Service |
158247 |
/* no free regions */
|
|
Packit Service |
158247 |
g_free (free_regs);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (type == BD_PART_TYPE_NORMAL) {
|
|
Packit Service |
158247 |
for (free_reg_p=free_regs; *free_reg_p; free_reg_p++) {
|
|
Packit Service |
158247 |
/* check if it has enough space and is not inside an extended partition */
|
|
Packit Service |
158247 |
if ((*free_reg_p)->size > size && !((*free_reg_p)->type & BD_PART_TYPE_LOGICAL))
|
|
Packit Service |
158247 |
/* if it is the first that would fit or if it is smaller than
|
|
Packit Service |
158247 |
what we found earlier, it is a better match */
|
|
Packit Service |
158247 |
if (!ret || ((*free_reg_p)->size < ret->size))
|
|
Packit Service |
158247 |
ret = *free_reg_p;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
} else if (type == BD_PART_TYPE_EXTENDED) {
|
|
Packit Service |
158247 |
for (free_reg_p=free_regs; *free_reg_p; free_reg_p++) {
|
|
Packit Service |
158247 |
/* if there already is an extended partition, there cannot be another one */
|
|
Packit Service |
158247 |
if ((*free_reg_p)->type & BD_PART_TYPE_LOGICAL) {
|
|
Packit Service |
158247 |
for (free_reg_p=free_regs; *free_reg_p; free_reg_p++)
|
|
Packit Service |
158247 |
bd_part_spec_free (*free_reg_p);
|
|
Packit Service |
158247 |
g_free (free_regs);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
/* check if it has enough space */
|
|
Packit Service |
158247 |
if ((*free_reg_p)->size > size)
|
|
Packit Service |
158247 |
/* if it is the first that would fit or if it is bigger than
|
|
Packit Service |
158247 |
what we found earlier, it is a better match */
|
|
Packit Service |
158247 |
if (!ret || ((*free_reg_p)->size > ret->size))
|
|
Packit Service |
158247 |
ret = *free_reg_p;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
} else if (type == BD_PART_TYPE_LOGICAL) {
|
|
Packit Service |
158247 |
for (free_reg_p=free_regs; *free_reg_p; free_reg_p++) {
|
|
Packit Service |
158247 |
/* check if it has enough space and is inside an extended partition */
|
|
Packit Service |
158247 |
if ((*free_reg_p)->size > size && ((*free_reg_p)->type & BD_PART_TYPE_LOGICAL))
|
|
Packit Service |
158247 |
/* if it is the first that would fit or if it is smaller than
|
|
Packit Service |
158247 |
what we found earlier, it is a better match */
|
|
Packit Service |
158247 |
if (!ret || ((*free_reg_p)->size < ret->size))
|
|
Packit Service |
158247 |
ret = *free_reg_p;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* free all the other specs and return the best one */
|
|
Packit Service |
158247 |
for (free_reg_p=free_regs; *free_reg_p; free_reg_p++)
|
|
Packit Service |
158247 |
if (*free_reg_p != ret)
|
|
Packit Service |
158247 |
bd_part_spec_free (*free_reg_p);
|
|
Packit Service |
158247 |
g_free (free_regs);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return ret;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
static PedConstraint* prepare_alignment_constraint (PedDevice *dev, PedDisk *disk, BDPartAlign align, gint *orig_flag_state) {
|
|
Packit Service |
158247 |
if (align == BD_PART_ALIGN_OPTIMAL) {
|
|
Packit Service |
158247 |
/* cylinder alignment does really weird things when turned on, let's not
|
|
Packit Service |
158247 |
deal with it in 21st century (the flag is reset back in the end) */
|
|
Packit Service |
158247 |
if (ped_disk_is_flag_available (disk, PED_DISK_CYLINDER_ALIGNMENT)) {
|
|
Packit Service |
158247 |
*orig_flag_state = ped_disk_get_flag (disk, PED_DISK_CYLINDER_ALIGNMENT);
|
|
Packit Service |
158247 |
ped_disk_set_flag (disk, PED_DISK_CYLINDER_ALIGNMENT, 0);
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
return ped_device_get_optimal_aligned_constraint (dev);
|
|
Packit Service |
158247 |
} else if (align == BD_PART_ALIGN_MINIMAL)
|
|
Packit Service |
158247 |
return ped_device_get_minimal_aligned_constraint (dev);
|
|
Packit Service |
158247 |
else
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
static void finish_alignment_constraint (PedDisk *disk, gint orig_flag_state) {
|
|
Packit Service |
158247 |
if (ped_disk_is_flag_available (disk, PED_DISK_CYLINDER_ALIGNMENT)) {
|
|
Packit Service |
158247 |
ped_disk_set_flag (disk, PED_DISK_CYLINDER_ALIGNMENT, orig_flag_state);
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
static gboolean resize_part (PedPartition *part, PedDevice *dev, PedDisk *disk, guint64 size, BDPartAlign align, GError **error) {
|
|
Packit Service |
158247 |
PedConstraint *constr = NULL;
|
|
Packit Service |
158247 |
PedGeometry *geom;
|
|
Packit Service |
158247 |
gint orig_flag_state = 0;
|
|
Packit Service |
158247 |
PedSector start;
|
|
Packit Service |
158247 |
PedSector end;
|
|
Packit Service |
158247 |
PedSector max_end;
|
|
Packit Service |
158247 |
PedSector new_size = 0;
|
|
Packit Service |
158247 |
gint status = 0;
|
|
Packit Service |
158247 |
PedSector tolerance = 0;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* It should be possible to pass the whole drive size a partition size,
|
|
Packit Service |
158247 |
* so -1 MiB for the first partition alignment,
|
|
Packit Service |
158247 |
* -1 MiB for creating this here as a logial partition
|
|
Packit Service |
158247 |
* and -1 MiB for end alingment.
|
|
Packit Service |
158247 |
* But only if the caller doesn't request no alignment which also means
|
|
Packit Service |
158247 |
* they strictly care about precise numbers. */
|
|
Packit Service |
158247 |
if (align != BD_PART_ALIGN_NONE)
|
|
Packit Service |
158247 |
tolerance = (PedSector) (4 MiB / dev->sector_size);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
constr = prepare_alignment_constraint (dev, disk, align, &orig_flag_state);
|
|
Packit Service |
158247 |
start = part->geom.start;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (!constr)
|
|
Packit Service |
158247 |
constr = ped_constraint_any (dev);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
geom = ped_disk_get_max_partition_geometry (disk, part, constr);
|
|
Packit Service |
158247 |
if (!ped_geometry_set_start (geom, start)) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to set partition start on device '%s'", dev->path);
|
|
Packit Service |
158247 |
ped_constraint_destroy (constr);
|
|
Packit Service |
158247 |
ped_geometry_destroy (geom);
|
|
Packit Service |
158247 |
finish_alignment_constraint (disk, orig_flag_state);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
if (size == 0) {
|
|
Packit Service |
158247 |
new_size = geom->length;
|
|
Packit Service |
158247 |
} else {
|
|
Packit Service |
158247 |
new_size = (size + dev->sector_size - 1) / dev->sector_size;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* If the maximum partition geometry is smaller than the requested size, but
|
|
Packit Service |
158247 |
the difference is acceptable, just adapt the size. */
|
|
Packit Service |
158247 |
if (new_size > geom->length && (new_size - geom->length) < tolerance)
|
|
Packit Service |
158247 |
new_size = geom->length;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
max_end = geom->end;
|
|
Packit Service |
158247 |
ped_geometry_destroy (geom);
|
|
Packit Service |
158247 |
geom = ped_geometry_new (dev, start, new_size);
|
|
Packit Service |
158247 |
if (!geom) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to create geometry for partition on device '%s'", dev->path);
|
|
Packit Service |
158247 |
ped_constraint_destroy (constr);
|
|
Packit Service |
158247 |
finish_alignment_constraint (disk, orig_flag_state);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (size != 0) {
|
|
Packit Service |
158247 |
end = ped_alignment_align_up (constr->end_align, constr->end_range, geom->end);
|
|
Packit Service |
158247 |
if (end > max_end && end < max_end + tolerance) {
|
|
Packit Service |
158247 |
end = max_end;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
} else {
|
|
Packit Service |
158247 |
end = geom->end;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
ped_constraint_destroy (constr);
|
|
Packit Service |
158247 |
if (!ped_geometry_set_end (geom, end)) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to change geometry for partition on device '%s'", dev->path);
|
|
Packit Service |
158247 |
ped_constraint_destroy (constr);
|
|
Packit Service |
158247 |
ped_geometry_destroy (geom);
|
|
Packit Service |
158247 |
finish_alignment_constraint (disk, orig_flag_state);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
constr = ped_constraint_exact (geom);
|
|
Packit Service |
158247 |
status = ped_disk_set_partition_geom (disk, part, constr, start, end);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (status == 0) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to set partition size on device '%s'", dev->path);
|
|
Packit Service |
158247 |
ped_geometry_destroy (geom);
|
|
Packit Service |
158247 |
ped_constraint_destroy (constr);
|
|
Packit Service |
158247 |
finish_alignment_constraint (disk, orig_flag_state);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
} else if (part->geom.start != start) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_FAIL, "Failed to meet partition start on device '%s'", dev->path);
|
|
Packit Service |
158247 |
ped_geometry_destroy (geom);
|
|
Packit Service |
158247 |
ped_constraint_destroy (constr);
|
|
Packit Service |
158247 |
finish_alignment_constraint (disk, orig_flag_state);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
} else if (part->geom.length < new_size - tolerance) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_FAIL, "Failed to meet partition size on device '%s'", dev->path);
|
|
Packit Service |
158247 |
ped_geometry_destroy (geom);
|
|
Packit Service |
158247 |
ped_constraint_destroy (constr);
|
|
Packit Service |
158247 |
finish_alignment_constraint (disk, orig_flag_state);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_geometry_destroy (geom);
|
|
Packit Service |
158247 |
ped_constraint_destroy (constr);
|
|
Packit Service |
158247 |
finish_alignment_constraint (disk, orig_flag_state);
|
|
Packit Service |
158247 |
return TRUE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
static PedPartition* add_part_to_disk (PedDevice *dev, PedDisk *disk, BDPartTypeReq type, guint64 start, guint64 size, BDPartAlign align, GError **error) {
|
|
Packit Service |
158247 |
PedPartition *part = NULL;
|
|
Packit Service |
158247 |
PedConstraint *constr = NULL;
|
|
Packit Service |
158247 |
PedGeometry *geom;
|
|
Packit Service |
158247 |
gint orig_flag_state = 0;
|
|
Packit Service |
158247 |
gint status = 0;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* convert start to sectors */
|
|
Packit Service |
158247 |
start = (start + (guint64)dev->sector_size - 1) / dev->sector_size;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
constr = prepare_alignment_constraint (dev, disk, align, &orig_flag_state);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (constr)
|
|
Packit Service |
158247 |
start = ped_alignment_align_up (constr->start_align, constr->start_range, (PedSector) start);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
geom = ped_geometry_new (dev, (PedSector) start, (PedSector) 1 MiB / dev->sector_size);
|
|
Packit Service |
158247 |
if (!geom) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to create geometry for a new partition on device '%s'", dev->path);
|
|
Packit Service |
158247 |
ped_constraint_destroy (constr);
|
|
Packit Service |
158247 |
finish_alignment_constraint (disk, orig_flag_state);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
part = ped_partition_new (disk, (PedPartitionType)type, NULL, geom->start, geom->end);
|
|
Packit Service |
158247 |
if (!part) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to create new partition on device '%s'", dev->path);
|
|
Packit Service |
158247 |
ped_constraint_destroy (constr);
|
|
Packit Service |
158247 |
ped_geometry_destroy (geom);
|
|
Packit Service |
158247 |
finish_alignment_constraint (disk, orig_flag_state);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (!constr)
|
|
Packit Service |
158247 |
constr = ped_constraint_exact (geom);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
status = ped_disk_add_partition (disk, part, constr);
|
|
Packit Service |
158247 |
if (status == 0) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed add partition to device '%s'", dev->path);
|
|
Packit Service |
158247 |
ped_geometry_destroy (geom);
|
|
Packit Service |
158247 |
ped_constraint_destroy (constr);
|
|
Packit Service |
158247 |
ped_partition_destroy (part);
|
|
Packit Service |
158247 |
finish_alignment_constraint (disk, orig_flag_state);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (!resize_part (part, dev, disk, size, align, error)) {
|
|
Packit Service |
158247 |
ped_geometry_destroy (geom);
|
|
Packit Service |
158247 |
ped_constraint_destroy (constr);
|
|
Packit Service |
158247 |
ped_disk_delete_partition (disk, part);
|
|
Packit Service |
158247 |
finish_alignment_constraint (disk, orig_flag_state);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
finish_alignment_constraint (disk, orig_flag_state);
|
|
Packit Service |
158247 |
ped_geometry_destroy (geom);
|
|
Packit Service |
158247 |
ped_constraint_destroy (constr);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return part;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_create_part:
|
|
Packit Service |
158247 |
* @disk: disk to create partition on
|
|
Packit Service |
158247 |
* @type: type of the partition to create (if %BD_PART_TYPE_REQ_NEXT, the
|
|
Packit Service |
158247 |
* partition type will be determined automatically based on the existing
|
|
Packit Service |
158247 |
* partitions)
|
|
Packit Service |
158247 |
* @start: where the partition should start (i.e. offset from the disk start)
|
|
Packit Service |
158247 |
* @size: desired size of the partition (if 0, a max-sized partition is created)
|
|
Packit Service |
158247 |
* @align: alignment to use for the partition
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: (transfer full): specification of the created partition or %NULL in case of error
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* NOTE: The resulting partition may start at a different position than given by
|
|
Packit Service |
158247 |
* @start and can have different size than @size due to alignment.
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: %BD_PART_TECH_MODE_MODIFY_TABLE + the tech according to the partition table type
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
BDPartSpec* bd_part_create_part (const gchar *disk, BDPartTypeReq type, guint64 start, guint64 size, BDPartAlign align, GError **error) {
|
|
Packit Service |
158247 |
PedDevice *dev = NULL;
|
|
Packit Service |
158247 |
PedDisk *ped_disk = NULL;
|
|
Packit Service |
158247 |
PedPartition *ped_part = NULL;
|
|
Packit Service |
158247 |
PedPartition *ext_part = NULL;
|
|
Packit Service |
158247 |
PedSector start_sector = 0;
|
|
Packit Service |
158247 |
gint last_num = 0;
|
|
Packit Service |
158247 |
gboolean succ = FALSE;
|
|
Packit Service |
158247 |
BDPartSpec *ret = NULL;
|
|
Packit Service |
158247 |
guint64 progress_id = 0;
|
|
Packit Service |
158247 |
gchar *msg = NULL;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
msg = g_strdup_printf ("Started adding partition to '%s'", disk);
|
|
Packit Service |
158247 |
progress_id = bd_utils_report_started (msg);
|
|
Packit Service |
158247 |
g_free (msg);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
dev = ped_device_get (disk);
|
|
Packit Service |
158247 |
if (!dev) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_INVAL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Device '%s' invalid or not existing", disk);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_disk = ped_disk_new (dev);
|
|
Packit Service |
158247 |
if (!ped_disk) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to read partition table on device '%s'", disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (type == BD_PART_TYPE_REQ_NEXT) {
|
|
Packit Service |
158247 |
ext_part = ped_disk_extended_partition (ped_disk);
|
|
Packit Service |
158247 |
start_sector = (PedSector) (start + dev->sector_size - 1) / dev->sector_size;
|
|
Packit Service |
158247 |
if (ext_part && (start_sector > ext_part->geom.start) && (start_sector < ext_part->geom.end)) {
|
|
Packit Service |
158247 |
/* partition's start is in the extended partition -> must be logical */
|
|
Packit Service |
158247 |
type = BD_PART_TYPE_REQ_LOGICAL;
|
|
Packit Service |
158247 |
} else if ((ped_disk_get_max_primary_partition_count (ped_disk) - 1 > ped_disk_get_primary_partition_count (ped_disk)) || ext_part) {
|
|
Packit Service |
158247 |
/* we have room for another primary partition or there already is an extended partition -> should/must be primary */
|
|
Packit Service |
158247 |
type = BD_PART_TYPE_REQ_NORMAL;
|
|
Packit Service |
158247 |
} else {
|
|
Packit Service |
158247 |
ped_part = add_part_to_disk (dev, ped_disk, BD_PART_TYPE_REQ_EXTENDED, start, 0, align, error);
|
|
Packit Service |
158247 |
if (!ped_part) {
|
|
Packit Service |
158247 |
/* error is already populated */
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
type = BD_PART_TYPE_REQ_LOGICAL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (type == BD_PART_TYPE_REQ_LOGICAL) {
|
|
Packit Service |
158247 |
/* Find the previous logical partition (if there's any) because we need
|
|
Packit Service |
158247 |
its end. If there's no such logical partition, we are creating the
|
|
Packit Service |
158247 |
first one and thus should only care about the extended partition's
|
|
Packit Service |
158247 |
start*/
|
|
Packit Service |
158247 |
last_num = ped_disk_get_last_partition_num (ped_disk);
|
|
Packit Service |
158247 |
ped_part = ped_disk_get_partition (ped_disk, last_num);
|
|
Packit Service |
158247 |
while (ped_part && (ped_part->type != PED_PARTITION_EXTENDED) &&
|
|
Packit Service |
158247 |
(ped_part->geom.start > (PedSector) (start / dev->sector_size)))
|
|
Packit Service |
158247 |
ped_part = ped_part->prev;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (!ped_part) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Failed to find suitable free region for a new logical partition.");
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (ped_part->type == PED_PARTITION_EXTENDED) {
|
|
Packit Service |
158247 |
/* can at minimal start where the first logical partition can start - the start of the extended partition + 1 MiB aligned up */
|
|
Packit Service |
158247 |
if (start < ((ped_part->geom.start * dev->sector_size) + 1 MiB + dev->sector_size - 1))
|
|
Packit Service |
158247 |
start = (ped_part->geom.start * dev->sector_size) + 1 MiB + dev->sector_size - 1;
|
|
Packit Service |
158247 |
} else {
|
|
Packit Service |
158247 |
/* can at minimal start where the next logical partition can start - the end of the previous partition + 1 MiB aligned up */
|
|
Packit Service |
158247 |
if (start < ((ped_part->geom.end * dev->sector_size) + 1 MiB + dev->sector_size - 1))
|
|
Packit Service |
158247 |
start = (ped_part->geom.end * dev->sector_size) + 1 MiB + dev->sector_size - 1;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_part = add_part_to_disk (dev, ped_disk, type, start, size, align, error);
|
|
Packit Service |
158247 |
if (!ped_part) {
|
|
Packit Service |
158247 |
/* error is already populated */
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
succ = disk_commit (ped_disk, disk, error);
|
|
Packit Service |
158247 |
if (succ)
|
|
Packit Service |
158247 |
ret = get_part_spec (dev, ped_disk, ped_part, error);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* the partition gets destroyed together with the disk*/
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, "Completed");
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return ret;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_delete_part:
|
|
Packit Service |
158247 |
* @disk: disk to remove the partition from
|
|
Packit Service |
158247 |
* @part: partition to remove
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: whether the @part partition was successfully deleted from @disk
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: %BD_PART_TECH_MODE_MODIFY_TABLE + the tech according to the partition table type
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
gboolean bd_part_delete_part (const gchar *disk, const gchar *part, GError **error) {
|
|
Packit Service |
158247 |
PedDevice *dev = NULL;
|
|
Packit Service |
158247 |
PedDisk *ped_disk = NULL;
|
|
Packit Service |
158247 |
PedPartition *ped_part = NULL;
|
|
Packit Service |
158247 |
const gchar *part_num_str = NULL;
|
|
Packit Service |
158247 |
gint part_num = 0;
|
|
Packit Service |
158247 |
gint status = 0;
|
|
Packit Service |
158247 |
gboolean ret = FALSE;
|
|
Packit Service |
158247 |
guint64 progress_id = 0;
|
|
Packit Service |
158247 |
gchar *msg = NULL;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
msg = g_strdup_printf ("Started deleting partition '%s'", part);
|
|
Packit Service |
158247 |
progress_id = bd_utils_report_started (msg);
|
|
Packit Service |
158247 |
g_free (msg);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (!part || (part && (*part == '\0'))) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition path given: '%s'", part);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
dev = ped_device_get (disk);
|
|
Packit Service |
158247 |
if (!dev) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_INVAL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Device '%s' invalid or not existing", disk);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_disk = ped_disk_new (dev);
|
|
Packit Service |
158247 |
if (!ped_disk) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to read partition table on device '%s'", disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
part_num_str = part + (strlen (part) - 1);
|
|
Packit Service |
158247 |
while (isdigit (*part_num_str) || (*part_num_str == '-')) {
|
|
Packit Service |
158247 |
part_num_str--;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
part_num_str++;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
part_num = atoi (part_num_str);
|
|
Packit Service |
158247 |
if (part_num == 0) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition path given: '%s'. Cannot extract partition number", part);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_part = ped_disk_get_partition (ped_disk, part_num);
|
|
Packit Service |
158247 |
if (!ped_part) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to get partition '%d' on device '%s'", part_num, disk);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
status = ped_disk_delete_partition (ped_disk, ped_part);
|
|
Packit Service |
158247 |
if (status == 0) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to delete partition '%d' on device '%s'", part_num, disk);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ret = disk_commit (ped_disk, disk, error);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, "Completed");
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return ret;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_resize_part:
|
|
Packit Service |
158247 |
* @disk: disk containing the paritition
|
|
Packit Service |
158247 |
* @part: partition to resize
|
|
Packit Service |
158247 |
* @size: new partition size, 0 for maximal size
|
|
Packit Service |
158247 |
* @align: alignment to use for the partition end
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: whether the @part partition was successfully resized on @disk to @size
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* NOTE: The resulting partition may be slightly bigger than requested due to alignment.
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: %BD_PART_TECH_MODE_MODIFY_TABLE + the tech according to the partition table type
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
gboolean bd_part_resize_part (const gchar *disk, const gchar *part, guint64 size, BDPartAlign align, GError **error) {
|
|
Packit Service |
158247 |
PedDevice *dev = NULL;
|
|
Packit Service |
158247 |
PedDisk *ped_disk = NULL;
|
|
Packit Service |
158247 |
PedPartition *ped_part = NULL;
|
|
Packit Service |
158247 |
const gchar *part_num_str = NULL;
|
|
Packit Service |
158247 |
gint part_num = 0;
|
|
Packit Service |
158247 |
gboolean ret = FALSE;
|
|
Packit Service |
158247 |
guint64 progress_id = 0;
|
|
Packit Service |
158247 |
gchar *msg = NULL;
|
|
Packit Service |
158247 |
guint64 old_size = 0;
|
|
Packit Service |
158247 |
guint64 new_size = 0;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
msg = g_strdup_printf ("Started resizing partition '%s'", part);
|
|
Packit Service |
158247 |
progress_id = bd_utils_report_started (msg);
|
|
Packit Service |
158247 |
g_free (msg);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (!part || (part && (*part == '\0'))) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition path given: '%s'", part);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
dev = ped_device_get (disk);
|
|
Packit Service |
158247 |
if (!dev) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_INVAL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Device '%s' invalid or not existing", disk);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_disk = ped_disk_new (dev);
|
|
Packit Service |
158247 |
if (!ped_disk) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to read partition table on device '%s'", disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
part_num_str = part + (strlen (part) - 1);
|
|
Packit Service |
158247 |
while (isdigit (*part_num_str) || (*part_num_str == '-')) {
|
|
Packit Service |
158247 |
part_num_str--;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
part_num_str++;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
part_num = atoi (part_num_str);
|
|
Packit Service |
158247 |
if (part_num == 0) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition path given: '%s'. Cannot extract partition number", part);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_part = ped_disk_get_partition (ped_disk, part_num);
|
|
Packit Service |
158247 |
if (!ped_part) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to get partition '%d' on device '%s'", part_num, disk);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
old_size = ped_part->geom.length * dev->sector_size;
|
|
Packit Service |
158247 |
if (!resize_part (ped_part, dev, ped_disk, size, align, error)) {
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
new_size = ped_part->geom.length * dev->sector_size;
|
|
Packit Service |
158247 |
if (old_size != new_size) {
|
|
Packit Service |
158247 |
gint fd = 0;
|
|
Packit Service |
158247 |
gint wait_us = 10 * 1000 * 1000; /* 10 seconds */
|
|
Packit Service |
158247 |
gint step_us = 100 * 1000; /* 100 microseconds */
|
|
Packit Service |
158247 |
guint64 block_size = 0;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ret = disk_commit (ped_disk, disk, error);
|
|
Packit Service |
158247 |
/* wait for partition to appear with new size */
|
|
Packit Service |
158247 |
while (wait_us > 0) {
|
|
Packit Service |
158247 |
fd = open (part, O_RDONLY);
|
|
Packit Service |
158247 |
if (fd != -1) {
|
|
Packit Service |
158247 |
if (ioctl (fd, BLKGETSIZE64, &block_size) != -1 && block_size == new_size) {
|
|
Packit Service |
158247 |
close (fd);
|
|
Packit Service |
158247 |
break;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
close (fd);
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
g_usleep (step_us);
|
|
Packit Service |
158247 |
wait_us -= step_us;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
} else {
|
|
Packit Service |
158247 |
ret = TRUE; /* not committing to disk */
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, "Completed");
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return ret;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
static gboolean set_gpt_flag (const gchar *device, int part_num, BDPartFlag flag, gboolean state, GError **error) {
|
|
Packit Service |
158247 |
const gchar *args[5] = {"sgdisk", "--attributes", NULL, device, NULL};
|
|
Packit Service |
158247 |
int bit_num = 0;
|
|
Packit Service |
158247 |
gboolean success = FALSE;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (!check_deps (&avail_deps, DEPS_SGDISK_MASK, deps, DEPS_LAST, &deps_check_lock, error))
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (flag == BD_PART_FLAG_GPT_SYSTEM_PART)
|
|
Packit Service |
158247 |
bit_num = 0;
|
|
Packit Service |
158247 |
else if (flag == BD_PART_FLAG_LEGACY_BOOT)
|
|
Packit Service |
158247 |
bit_num = 2;
|
|
Packit Service |
158247 |
else if (flag == BD_PART_FLAG_GPT_READ_ONLY)
|
|
Packit Service |
158247 |
bit_num = 60;
|
|
Packit Service |
158247 |
else if (flag == BD_PART_FLAG_GPT_HIDDEN)
|
|
Packit Service |
158247 |
bit_num = 62;
|
|
Packit Service |
158247 |
else if (flag == BD_PART_FLAG_GPT_NO_AUTOMOUNT)
|
|
Packit Service |
158247 |
bit_num = 63;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
args[2] = g_strdup_printf ("%d:%s:%d", part_num, state ? "set" : "clear", bit_num);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
success = bd_utils_exec_and_report_error (args, NULL, error);
|
|
Packit Service |
158247 |
g_free ((gchar *) args[2]);
|
|
Packit Service |
158247 |
return success;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
static gboolean set_gpt_flags (const gchar *device, int part_num, guint64 flags, GError **error) {
|
|
Packit Service |
158247 |
const gchar *args[5] = {"sgdisk", "--attributes", NULL, device, NULL};
|
|
Packit Service |
158247 |
guint64 real_flags = 0;
|
|
Packit Service |
158247 |
gchar *mask_str = NULL;
|
|
Packit Service |
158247 |
gboolean success = FALSE;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (!check_deps (&avail_deps, DEPS_SGDISK_MASK, deps, DEPS_LAST, &deps_check_lock, error))
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (flags & BD_PART_FLAG_GPT_SYSTEM_PART)
|
|
Packit Service |
158247 |
real_flags |= 1; /* 1 << 0 */
|
|
Packit Service |
158247 |
if (flags & BD_PART_FLAG_LEGACY_BOOT)
|
|
Packit Service |
158247 |
real_flags |= 4; /* 1 << 2 */
|
|
Packit Service |
158247 |
if (flags & BD_PART_FLAG_GPT_READ_ONLY)
|
|
Packit Service |
158247 |
real_flags |= 0x1000000000000000; /* 1 << 60 */
|
|
Packit Service |
158247 |
if (flags & BD_PART_FLAG_GPT_HIDDEN)
|
|
Packit Service |
158247 |
real_flags |= 0x4000000000000000; /* 1 << 62 */
|
|
Packit Service |
158247 |
if (flags & BD_PART_FLAG_GPT_NO_AUTOMOUNT)
|
|
Packit Service |
158247 |
real_flags |= 0x8000000000000000; /* 1 << 63 */
|
|
Packit Service |
158247 |
mask_str = g_strdup_printf ("%.16"PRIx64, real_flags);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
args[2] = g_strdup_printf ("%d:=:%s", part_num, mask_str);
|
|
Packit Service |
158247 |
g_free (mask_str);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
success = bd_utils_exec_and_report_error (args, NULL, error);
|
|
Packit Service |
158247 |
g_free ((gchar *) args[2]);
|
|
Packit Service |
158247 |
return success;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_set_part_flag:
|
|
Packit Service |
158247 |
* @disk: disk the partition belongs to
|
|
Packit Service |
158247 |
* @part: partition to set the flag on
|
|
Packit Service |
158247 |
* @flag: flag to set
|
|
Packit Service |
158247 |
* @state: state to set for the @flag (%TRUE = enabled)
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: whether the flag @flag was successfully set on the @part partition
|
|
Packit Service |
158247 |
* or not.
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: %BD_PART_TECH_MODE_MODIFY_PART + the tech according to the partition table type
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
gboolean bd_part_set_part_flag (const gchar *disk, const gchar *part, BDPartFlag flag, gboolean state, GError **error) {
|
|
Packit Service |
158247 |
PedDevice *dev = NULL;
|
|
Packit Service |
158247 |
PedDisk *ped_disk = NULL;
|
|
Packit Service |
158247 |
PedPartition *ped_part = NULL;
|
|
Packit Service |
158247 |
PedPartitionFlag ped_flag = PED_PARTITION_FIRST_FLAG;
|
|
Packit Service |
158247 |
const gchar *part_num_str = NULL;
|
|
Packit Service |
158247 |
gint part_num = 0;
|
|
Packit Service |
158247 |
gint status = 0;
|
|
Packit Service |
158247 |
gboolean ret = FALSE;
|
|
Packit Service |
158247 |
guint64 progress_id = 0;
|
|
Packit Service |
158247 |
gchar *msg = NULL;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
msg = g_strdup_printf ("Started setting flag on the partition '%s'", part);
|
|
Packit Service |
158247 |
progress_id = bd_utils_report_started (msg);
|
|
Packit Service |
158247 |
g_free (msg);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* TODO: share this code with the other functions modifying a partition */
|
|
Packit Service |
158247 |
if (!part || (part && (*part == '\0'))) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition path given: '%s'", part);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
dev = ped_device_get (disk);
|
|
Packit Service |
158247 |
if (!dev) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_INVAL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Device '%s' invalid or not existing", disk);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_disk = ped_disk_new (dev);
|
|
Packit Service |
158247 |
if (!ped_disk) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to read partition table on device '%s'", disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
part_num_str = part + (strlen (part) - 1);
|
|
Packit Service |
158247 |
while (isdigit (*part_num_str) || (*part_num_str == '-')) {
|
|
Packit Service |
158247 |
part_num_str--;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
part_num_str++;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
part_num = atoi (part_num_str);
|
|
Packit Service |
158247 |
if (part_num == 0) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition path given: '%s'. Cannot extract partition number", part);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_part = ped_disk_get_partition (ped_disk, part_num);
|
|
Packit Service |
158247 |
if (!ped_part) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to get partition '%d' on device '%s'", part_num, disk);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* our flags are 1s shifted to the bit determined by parted's flags
|
|
Packit Service |
158247 |
* (i.e. 1 << 3 instead of 3, etc.) */
|
|
Packit Service |
158247 |
if (flag < BD_PART_FLAG_BASIC_LAST) {
|
|
Packit Service |
158247 |
ped_flag = (PedPartitionFlag) log2 ((double) flag);
|
|
Packit Service |
158247 |
status = ped_partition_set_flag (ped_part, ped_flag, (int) state);
|
|
Packit Service |
158247 |
if (status == 0) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to set flag on partition '%d' on device '%s'", part_num, disk);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ret = disk_commit (ped_disk, disk, error);
|
|
Packit Service |
158247 |
} else {
|
|
Packit Service |
158247 |
if (g_strcmp0 (ped_disk->type->name, "gpt") == 0)
|
|
Packit Service |
158247 |
ret = set_gpt_flag (disk, part_num, flag, state, error);
|
|
Packit Service |
158247 |
else
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Cannot set a GPT flag on a non-GPT disk");
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, "Completed");
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return ret;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_set_disk_flag:
|
|
Packit Service |
158247 |
* @disk: disk the partition belongs to
|
|
Packit Service |
158247 |
* @flag: flag to set
|
|
Packit Service |
158247 |
* @state: state to set for the @flag (%TRUE = enabled)
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: whether the flag @flag was successfully set on the @disk or not
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: %BD_PART_TECH_MODE_MODIFY_TABLE + the tech according to the partition table type
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
gboolean bd_part_set_disk_flag (const gchar *disk, BDPartDiskFlag flag, gboolean state, GError **error) {
|
|
Packit Service |
158247 |
PedDevice *dev = NULL;
|
|
Packit Service |
158247 |
PedDisk *ped_disk = NULL;
|
|
Packit Service |
158247 |
gint status = 0;
|
|
Packit Service |
158247 |
gboolean ret = FALSE;
|
|
Packit Service |
158247 |
guint64 progress_id = 0;
|
|
Packit Service |
158247 |
gchar *msg = NULL;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
msg = g_strdup_printf ("Started setting flag on the disk '%s'", disk);
|
|
Packit Service |
158247 |
progress_id = bd_utils_report_started (msg);
|
|
Packit Service |
158247 |
g_free (msg);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
dev = ped_device_get (disk);
|
|
Packit Service |
158247 |
if (!dev) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_INVAL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Device '%s' invalid or not existing", disk);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_disk = ped_disk_new (dev);
|
|
Packit Service |
158247 |
if (!ped_disk) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to read partition table on device '%s'", disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* right now we only support this one flag */
|
|
Packit Service |
158247 |
if (flag == BD_PART_DISK_FLAG_GPT_PMBR_BOOT) {
|
|
Packit Service |
158247 |
status = ped_disk_set_flag (ped_disk, PED_DISK_GPT_PMBR_BOOT, (int) state);
|
|
Packit Service |
158247 |
if (status == 0) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to set flag on disk '%s'", disk);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ret = disk_commit (ped_disk, disk, error);
|
|
Packit Service |
158247 |
} else {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid or unsupported flag given: %d", flag);
|
|
Packit Service |
158247 |
ret = FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, "Completed");
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return ret;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_set_part_flags:
|
|
Packit Service |
158247 |
* @disk: disk the partition belongs to
|
|
Packit Service |
158247 |
* @part: partition to set the flag on
|
|
Packit Service |
158247 |
* @flags: flags to set (mask combined from #BDPartFlag numbers)
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: whether the @flags were successfully set on the @part partition or
|
|
Packit Service |
158247 |
* not
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Note: Unsets all the other flags on the partition.
|
|
Packit Service |
158247 |
* Only GPT-specific flags and the legacy boot flag are supported on GPT
|
|
Packit Service |
158247 |
* partition tables.
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: %BD_PART_TECH_MODE_MODIFY_PART + the tech according to the partition table type
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
gboolean bd_part_set_part_flags (const gchar *disk, const gchar *part, guint64 flags, GError **error) {
|
|
Packit Service |
158247 |
PedDevice *dev = NULL;
|
|
Packit Service |
158247 |
PedDisk *ped_disk = NULL;
|
|
Packit Service |
158247 |
PedPartition *ped_part = NULL;
|
|
Packit Service |
158247 |
const gchar *part_num_str = NULL;
|
|
Packit Service |
158247 |
gint part_num = 0;
|
|
Packit Service |
158247 |
int i = 0;
|
|
Packit Service |
158247 |
gint status = 0;
|
|
Packit Service |
158247 |
gboolean ret = FALSE;
|
|
Packit Service |
158247 |
guint64 progress_id = 0;
|
|
Packit Service |
158247 |
gchar *msg = NULL;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
msg = g_strdup_printf ("Started setting flags on the partition '%s'", part);
|
|
Packit Service |
158247 |
progress_id = bd_utils_report_started (msg);
|
|
Packit Service |
158247 |
g_free (msg);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* TODO: share this code with the other functions modifying a partition */
|
|
Packit Service |
158247 |
if (!part || (part && (*part == '\0'))) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition path given: '%s'", part);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
dev = ped_device_get (disk);
|
|
Packit Service |
158247 |
if (!dev) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_INVAL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Device '%s' invalid or not existing", disk);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_disk = ped_disk_new (dev);
|
|
Packit Service |
158247 |
if (!ped_disk) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to read partition table on device '%s'", disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
part_num_str = part + (strlen (part) - 1);
|
|
Packit Service |
158247 |
while (isdigit (*part_num_str) || (*part_num_str == '-')) {
|
|
Packit Service |
158247 |
part_num_str--;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
part_num_str++;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
part_num = atoi (part_num_str);
|
|
Packit Service |
158247 |
if (part_num == 0) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition path given: '%s'. Cannot extract partition number", part);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* Do not let libparted touch gpt partition tables */
|
|
Packit Service |
158247 |
if (g_strcmp0 (ped_disk->type->name, "gpt") == 0) {
|
|
Packit Service |
158247 |
ret = set_gpt_flags (disk, part_num, flags, error);
|
|
Packit Service |
158247 |
} else {
|
|
Packit Service |
158247 |
ped_part = ped_disk_get_partition (ped_disk, part_num);
|
|
Packit Service |
158247 |
if (!ped_part) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to get partition '%d' on device '%s'", part_num, disk);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* our flags are 1s shifted to the bit determined by parted's flags
|
|
Packit Service |
158247 |
* (i.e. 1 << 3 instead of 3, etc.) */
|
|
Packit Service |
158247 |
for (i=1; i <= (int) log2 ((double)BD_PART_FLAG_BASIC_LAST); i++) {
|
|
Packit Service |
158247 |
if ((1 << i) & flags)
|
|
Packit Service |
158247 |
status = ped_partition_set_flag (ped_part, (PedPartitionFlag) i, (int) 1);
|
|
Packit Service |
158247 |
else if (ped_partition_is_flag_available (ped_part, (PedPartitionFlag) i))
|
|
Packit Service |
158247 |
status = ped_partition_set_flag (ped_part, (PedPartitionFlag) i, (int) 0);
|
|
Packit Service |
158247 |
if (status == 0) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to set flag on the partition '%d' on device '%s'", part_num, disk);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ret = disk_commit (ped_disk, disk, error);
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, "Completed");
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return ret;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_set_part_name:
|
|
Packit Service |
158247 |
* @disk: device the partition belongs to
|
|
Packit Service |
158247 |
* @part: partition the should be set for
|
|
Packit Service |
158247 |
* @name: name to set
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: whether the name was successfully set or not
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: %BD_PART_TECH_MODE_MODIFY_PART + the tech according to the partition table type
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
gboolean bd_part_set_part_name (const gchar *disk, const gchar *part, const gchar *name, GError **error) {
|
|
Packit Service |
158247 |
PedDevice *dev = NULL;
|
|
Packit Service |
158247 |
PedDisk *ped_disk = NULL;
|
|
Packit Service |
158247 |
PedPartition *ped_part = NULL;
|
|
Packit Service |
158247 |
const gchar *part_num_str = NULL;
|
|
Packit Service |
158247 |
gint part_num = 0;
|
|
Packit Service |
158247 |
gint status = 0;
|
|
Packit Service |
158247 |
gboolean ret = FALSE;
|
|
Packit Service |
158247 |
guint64 progress_id = 0;
|
|
Packit Service |
158247 |
gchar *msg = NULL;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
msg = g_strdup_printf ("Started setting name on the partition '%s'", part);
|
|
Packit Service |
158247 |
progress_id = bd_utils_report_started (msg);
|
|
Packit Service |
158247 |
g_free (msg);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* TODO: share this code with the other functions modifying a partition */
|
|
Packit Service |
158247 |
if (!part || (part && (*part == '\0'))) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition path given: '%s'", part);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
dev = ped_device_get (disk);
|
|
Packit Service |
158247 |
if (!dev) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_INVAL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Device '%s' invalid or not existing", disk);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_disk = ped_disk_new (dev);
|
|
Packit Service |
158247 |
if (!ped_disk) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to read partition table on device '%s'", disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
if (!(ped_disk->type->features & PED_DISK_TYPE_PARTITION_NAME)) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Partition names unsupported on the device '%s' ('%s')", disk,
|
|
Packit Service |
158247 |
ped_disk->type->name);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
part_num_str = part + (strlen (part) - 1);
|
|
Packit Service |
158247 |
while (isdigit (*part_num_str) || (*part_num_str == '-')) {
|
|
Packit Service |
158247 |
part_num_str--;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
part_num_str++;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
part_num = atoi (part_num_str);
|
|
Packit Service |
158247 |
if (part_num == 0) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition path given: '%s'. Cannot extract partition number", part);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_part = ped_disk_get_partition (ped_disk, part_num);
|
|
Packit Service |
158247 |
if (!ped_part) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to get partition '%d' on device '%s'", part_num, disk);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
status = ped_partition_set_name (ped_part, name);
|
|
Packit Service |
158247 |
if (status == 0) {
|
|
Packit Service |
158247 |
set_parted_error (error, BD_PART_ERROR_FAIL);
|
|
Packit Service |
158247 |
g_prefix_error (error, "Failed to set name on the partition '%d' on device '%s'", part_num, disk);
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ret = disk_commit (ped_disk, disk, error);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
ped_disk_destroy (ped_disk);
|
|
Packit Service |
158247 |
ped_device_destroy (dev);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, "Completed");
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return ret;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_set_part_type:
|
|
Packit Service |
158247 |
* @disk: device the partition belongs to
|
|
Packit Service |
158247 |
* @part: partition the should be set for
|
|
Packit Service |
158247 |
* @type_guid: GUID of the type
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: whether the @type_guid type was successfully set for @part or not
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: %BD_PART_TECH_GPT-%BD_PART_TECH_MODE_MODIFY_PART
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
gboolean bd_part_set_part_type (const gchar *disk, const gchar *part, const gchar *type_guid, GError **error) {
|
|
Packit Service |
158247 |
const gchar *args[5] = {"sgdisk", "--typecode", NULL, disk, NULL};
|
|
Packit Service |
158247 |
const gchar *part_num_str = NULL;
|
|
Packit Service |
158247 |
gboolean success = FALSE;
|
|
Packit Service |
158247 |
guint64 progress_id = 0;
|
|
Packit Service |
158247 |
gchar *msg = NULL;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (!check_deps (&avail_deps, DEPS_SGDISK_MASK, deps, DEPS_LAST, &deps_check_lock, error))
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
msg = g_strdup_printf ("Started setting type on the partition '%s'", part);
|
|
Packit Service |
158247 |
progress_id = bd_utils_report_started (msg);
|
|
Packit Service |
158247 |
g_free (msg);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (!part || (part && (*part == '\0'))) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition path given: '%s'", part);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
part_num_str = part + (strlen (part) - 1);
|
|
Packit Service |
158247 |
while (isdigit (*part_num_str) || (*part_num_str == '-')) {
|
|
Packit Service |
158247 |
part_num_str--;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
part_num_str++;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if ((g_strcmp0 (part_num_str, "0") != 0) && (atoi (part_num_str) == 0)) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition path given: '%s'. Cannot extract partition number", part);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
args[2] = g_strdup_printf ("%s:%s", part_num_str, type_guid);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
success = bd_utils_exec_and_report_error (args, NULL, error);
|
|
Packit Service |
158247 |
g_free ((gchar*) args[2]);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, "Completed");
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return success;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_set_part_id:
|
|
Packit Service |
158247 |
* @disk: device the partition belongs to
|
|
Packit Service |
158247 |
* @part: partition the should be set for
|
|
Packit Service |
158247 |
* @part_id: partition Id
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: whether the @part_id type was successfully set for @part or not
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: %BD_PART_TECH_MODE_MODIFY_PART + the tech according to the partition table type
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
gboolean bd_part_set_part_id (const gchar *disk, const gchar *part, const gchar *part_id, GError **error) {
|
|
Packit Service |
158247 |
const gchar *args[6] = {"sfdisk", "--id", disk, NULL, part_id, NULL};
|
|
Packit Service |
158247 |
const gchar *part_num_str = NULL;
|
|
Packit Service |
158247 |
gboolean success = FALSE;
|
|
Packit Service |
158247 |
guint64 progress_id = 0;
|
|
Packit Service |
158247 |
guint64 part_id_int = 0;
|
|
Packit Service |
158247 |
gchar *msg = NULL;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (!check_deps (&avail_deps, DEPS_SFDISK_MASK, deps, DEPS_LAST, &deps_check_lock, error))
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
msg = g_strdup_printf ("Started setting id on the partition '%s'", part);
|
|
Packit Service |
158247 |
progress_id = bd_utils_report_started (msg);
|
|
Packit Service |
158247 |
g_free (msg);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (!part || (part && (*part == '\0'))) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition path given: '%s'", part);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
part_num_str = part + (strlen (part) - 1);
|
|
Packit Service |
158247 |
while (isdigit (*part_num_str) || (*part_num_str == '-')) {
|
|
Packit Service |
158247 |
part_num_str--;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
part_num_str++;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
part_id_int = g_ascii_strtoull (part_id, NULL, 0);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (part_id_int == 0) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition id given: '%s'.", part_id);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (part_id_int == 0x05 || part_id_int == 0x0f || part_id_int == 0x85) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Cannot change partition id to extended.");
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if ((g_strcmp0 (part_num_str, "0") != 0) && (atoi (part_num_str) == 0)) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition path given: '%s'. Cannot extract partition number", part);
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, (*error)->message);
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
args[3] = g_strdup (part_num_str);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
success = bd_utils_exec_and_report_error (args, NULL, error);
|
|
Packit Service |
158247 |
g_free ((gchar*) args[3]);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
bd_utils_report_finished (progress_id, "Completed");
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return success;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_get_part_id:
|
|
Packit Service |
158247 |
* @disk: device the partition belongs to
|
|
Packit Service |
158247 |
* @part: partition the should be set for
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns (transfer full): partition id type or %NULL in case of error
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: %BD_PART_TECH_MODE_QUERY_PART + the tech according to the partition table type
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
gchar* bd_part_get_part_id (const gchar *disk, const gchar *part, GError **error) {
|
|
Packit Service |
158247 |
const gchar *args[5] = {"sfdisk", "--id", disk, NULL, NULL};
|
|
Packit Service |
158247 |
const gchar *part_num_str = NULL;
|
|
Packit Service |
158247 |
gchar *output = NULL;
|
|
Packit Service |
158247 |
gchar *ret = NULL;
|
|
Packit Service |
158247 |
gboolean success = FALSE;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (!check_deps (&avail_deps, DEPS_SFDISK_MASK, deps, DEPS_LAST, &deps_check_lock, error))
|
|
Packit Service |
158247 |
return FALSE;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if (!part || (part && (*part == '\0'))) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition path given: '%s'", part);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
part_num_str = part + (strlen (part) - 1);
|
|
Packit Service |
158247 |
while (isdigit (*part_num_str) || (*part_num_str == '-')) {
|
|
Packit Service |
158247 |
part_num_str--;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
part_num_str++;
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
if ((g_strcmp0 (part_num_str, "0") != 0) && (atoi (part_num_str) == 0)) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition path given: '%s'. Cannot extract partition number", part);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
args[3] = g_strdup (part_num_str);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
success = bd_utils_exec_and_capture_output (args, NULL, &output, error);
|
|
Packit Service |
158247 |
if (!success) {
|
|
Packit Service |
158247 |
g_free ((gchar *) args[3]);
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
output = g_strstrip (output);
|
|
Packit Service |
158247 |
ret = g_strdup_printf ("0x%s", output);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
g_free (output);
|
|
Packit Service |
158247 |
g_free ((gchar*) args[3]);
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return ret;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_get_part_table_type_str:
|
|
Packit Service |
158247 |
* @type: table type to get string representation for
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: (transfer none): string representation of @table_type
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: the tech according to @type
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
const gchar* bd_part_get_part_table_type_str (BDPartTableType type, GError **error) {
|
|
Packit Service |
158247 |
if (type >= BD_PART_TABLE_UNDEF) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL,
|
|
Packit Service |
158247 |
"Invalid partition table type given");
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return table_type_str[type];
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_get_flag_str:
|
|
Packit Service |
158247 |
* @flag: flag to get string representation for
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: (transfer none): string representation of @flag
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: always available
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
const gchar* bd_part_get_flag_str (BDPartFlag flag, GError **error) {
|
|
Packit Service |
158247 |
if (flag < BD_PART_FLAG_BASIC_LAST)
|
|
Packit Service |
158247 |
return ped_partition_flag_get_name ((PedPartitionFlag) log2 ((double) flag));
|
|
Packit Service |
158247 |
if (flag == BD_PART_FLAG_GPT_SYSTEM_PART)
|
|
Packit Service |
158247 |
return "system partition";
|
|
Packit Service |
158247 |
if (flag == BD_PART_FLAG_GPT_READ_ONLY)
|
|
Packit Service |
158247 |
return "read-only";
|
|
Packit Service |
158247 |
if (flag == BD_PART_FLAG_GPT_HIDDEN)
|
|
Packit Service |
158247 |
return "hidden";
|
|
Packit Service |
158247 |
if (flag == BD_PART_FLAG_GPT_NO_AUTOMOUNT)
|
|
Packit Service |
158247 |
return "do not automount";
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/* no other choice */
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL, "Invalid flag given");
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
/**
|
|
Packit Service |
158247 |
* bd_part_get_type_str:
|
|
Packit Service |
158247 |
* @type: type to get string representation for
|
|
Packit Service |
158247 |
* @error: (out): place to store error (if any)
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Returns: (transfer none): string representation of @type
|
|
Packit Service |
158247 |
*
|
|
Packit Service |
158247 |
* Tech category: always available
|
|
Packit Service |
158247 |
*/
|
|
Packit Service |
158247 |
const gchar* bd_part_get_type_str (BDPartType type, GError **error) {
|
|
Packit Service |
158247 |
if (type > BD_PART_TYPE_PROTECTED) {
|
|
Packit Service |
158247 |
g_set_error (error, BD_PART_ERROR, BD_PART_ERROR_INVAL, "Invalid partition type given");
|
|
Packit Service |
158247 |
return NULL;
|
|
Packit Service |
158247 |
}
|
|
Packit Service |
158247 |
|
|
Packit Service |
158247 |
return ped_partition_type_get_name ((PedPartitionType) type);
|
|
Packit Service |
158247 |
}
|