## Process this file with automake to produce Makefile.in
-SUBDIRS = data src doc tools policy po tests
+SUBDIRS = data udisks src doc tools policy po tests
# Creating ChangeLog from git log (taken from cairo/Makefile.am):
ChangeLog: $(srcdir)/ChangeLog
Makefile
data/Makefile
data/udisks.pc
+udisks/Makefile
src/Makefile
-src/helpers/Makefile
-src/probers/Makefile
tools/Makefile
doc/Makefile
doc/version.xml
## Process this file with automake to produce Makefile.in
-SUBDIRS = helpers probers
+SUBDIRS =
NULL =
-DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
-DPACKAGE_LIB_DIR=\""$(libdir)"\" \
-D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
- $(DBUS_GLIB_CFLAGS) \
+ -DUDISKS_API_IS_SUBJECT_TO_CHANGE \
$(POLKIT_GOBJECT_1_CFLAGS) \
$(GUDEV_CFLAGS) \
$(GLIB_CFLAGS) \
$(GIO_CFLAGS) \
$(NULL)
-generated-bindings.stamp : Makefile.am $(top_srcdir)/data/org.freedesktop.UDisks.xml $(top_srcdir)/data/org.freedesktop.UDisks.Device.xml
- gdbus-codegen \
- --strip-prefix org.freedesktop.UDisks. \
- --output-prefix generated \
- $(top_srcdir)/data/org.freedesktop.UDisks.xml \
- $(NULL)
-
-BUILT_SOURCES = \
- generated-bindings.stamp \
- generated-bindings.h \
- generated-bindingsprivate.h generated-bindingsprivate.c \
- generated-blockdevice.h generated-blockdevice.c \
- generated-marshallers.list \
- generated-marshallers.h generated-marshallers.c \
- generated-types.h \
- $(NULL)
-
libexec_PROGRAMS = udisks-daemon
udisks_daemon_SOURCES = \
$(BUILT_SOURCES) \
$(NULL)
-#udisks_daemon_SOURCES = \
-# types.h \
-# private.h \
-# profile.h \
-# daemon.h daemon.c \
-# device.h device.c \
-# device-private.h device-private.c \
-# adapter.h adapter.c \
-# adapter-private.h adapter-private.c \
-# expander.h expander.c \
-# expander-private.h expander-private.c \
-# port.h port.c \
-# port-private.h port-private.c \
-# mount-file.h mount-file.c \
-# mount.h mount.c \
-# mount-monitor.h mount-monitor.c \
-# inhibitor.h inhibitor.c \
-# poller.h poller.c \
-# main.c \
-# $(BUILT_SOURCES) \
-# $(NULL)
-#
-
udisks_daemon_CPPFLAGS = \
- -I$(top_srcdir)/src \
+ -I$(top_srcdir) \
-DG_LOG_DOMAIN=\"udisks-daemon\" \
- $(DISABLE_DEPRECATED) \
$(AM_CPPFLAGS) \
$(NULL)
udisks_daemon_LDADD = \
$(GIO_LIBS) \
- $(DBUS_GLIB_LIBS) \
$(POLKIT_GOBJECT_1_LIBS) \
$(GUDEV_LIBS) \
$(LIBATASMART_LIBS) \
+ $(top_builddir)/udisks/libudisks.la \
$(NULL)
# ----------------------------------------------------------------------------------------------------
-polkitmodulesdir = $(libdir)/polkit-1/extensions
-polkitmodules_LTLIBRARIES = libudisks-action-lookup.la
-
-libudisks_action_lookup_la_SOURCES = \
- polkit-action-lookup.c \
- $(NULL)
-
-libudisks_action_lookup_la_CFLAGS = \
- -DPOLKIT_BACKEND_I_KNOW_API_IS_SUBJECT_TO_CHANGE \
- -DG_LOG_DOMAIN=\"UDisks-Action-Lookup\" \
- $(POLKIT_BACKEND_1_CFLAGS) \
- $(NULL)
-
-libudisks_action_lookup_la_LDFLAGS = \
- -export_dynamic -avoid-version -module -no-undefined \
- -export-symbols-regex '^g_io_module_(load|unload)' \
- $(POLKIT_BACKEND_1_LIBS) \
- $(NULL)
-
-libudisks_action_lookup_la_LIBADD = \
- $(NULL)
-
-# ----------------------------------------------------------------------------------------------------
-
-CLEANFILES = $(BUILT_SOURCES)
-
-EXTRA_DIST = \
- marshal.list \
- $(NULL)
-
install-data-local:
-$(mkdir_p) $(DESTDIR)$(localstatedir)/lib/udisks
-chmod 0700 $(DESTDIR)$(localstatedir)/lib/udisks
+++ /dev/null
-udisks-helper-ata-smart-collect
-udisks-helper-ata-smart-selftest
-udisks-helper-change-filesystem-label
-udisks-helper-create-partition
-udisks-helper-create-partition-table
-udisks-helper-delete-partition
-udisks-helper-drive-benchmark
-udisks-helper-drive-detach
-udisks-helper-drive-poll
-udisks-helper-fstab-mounter
-udisks-helper-linux-md-check
-udisks-helper-linux-md-remove-component
-udisks-helper-mkfs
-udisks-helper-modify-partition
+++ /dev/null
-
-NULL =
-
-INCLUDES = \
- -I$(top_builddir)/src -I$(top_srcdir)/src \
- -DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
- -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
- -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
- -DPACKAGE_BIN_DIR=\""$(bindir)"\" \
- -DPACKAGE_LOCALSTATE_DIR=\""$(localstatedir)"\" \
- -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
- -DPACKAGE_LIB_DIR=\""$(libdir)"\" \
- -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
- $(DBUS_GLIB_CFLAGS) \
- $(POLKIT_GOBJECT_1_CFLAGS) \
- $(GUDEV_CFLAGS) \
- $(GLIB_CFLAGS) \
- $(GIO_CFLAGS)
-
-libexec_PROGRAMS = \
- udisks-helper-mkfs \
- udisks-helper-delete-partition \
- udisks-helper-create-partition \
- udisks-helper-modify-partition \
- udisks-helper-create-partition-table \
- udisks-helper-change-filesystem-label \
- udisks-helper-linux-md-remove-component \
- udisks-helper-fstab-mounter \
- udisks-helper-ata-smart-collect \
- udisks-helper-ata-smart-selftest \
- udisks-helper-drive-detach \
- udisks-helper-drive-poll \
- udisks-helper-linux-md-check \
- udisks-helper-drive-benchmark \
- $(NULL)
-
-noinst_LTLIBRARIES = libpartutil.la
-libpartutil_la_SOURCES = partutil.h partutil.c
-libpartutil_la_CPPFLAGS = $(LIBPARTED_CFLAGS)
-libpartutil_la_LIBADD = $(LIBPARTED_LIBS)
-
-dist_libexec_SCRIPTS = \
- udisks-helper-change-luks-password \
- udisks-helper-mdadm-expand \
- $(NULL)
-
-udisks_helper_mkfs_SOURCES = job-shared.h job-mkfs.c
-udisks_helper_mkfs_CPPFLAGS = $(AM_CPPFLAGS)
-udisks_helper_mkfs_LDADD = $(GLIB_LIBS)
-
-udisks_helper_delete_partition_SOURCES = job-shared.h job-delete-partition.c
-udisks_helper_delete_partition_CPPFLAGS = $(AM_CPPFLAGS)
-udisks_helper_delete_partition_LDADD = $(GLIB_LIBS) libpartutil.la
-
-udisks_helper_create_partition_SOURCES = job-shared.h job-create-partition.c
-udisks_helper_create_partition_CPPFLAGS = $(AM_CPPFLAGS) $(GUDEV_CFLAGS)
-udisks_helper_create_partition_LDADD = $(GLIB_LIBS) $(GUDEV_LIBS) libpartutil.la
-
-udisks_helper_modify_partition_SOURCES = job-shared.h job-modify-partition.c
-udisks_helper_modify_partition_CPPFLAGS = $(AM_CPPFLAGS)
-udisks_helper_modify_partition_LDADD = $(GLIB_LIBS) libpartutil.la
-
-udisks_helper_create_partition_table_SOURCES = job-shared.h job-create-partition-table.c
-udisks_helper_create_partition_table_CPPFLAGS = $(AM_CPPFLAGS)
-udisks_helper_create_partition_table_LDADD = $(GLIB_LIBS) libpartutil.la
-
-udisks_helper_change_filesystem_label_SOURCES = job-shared.h job-change-filesystem-label.c
-udisks_helper_change_filesystem_label_CPPFLAGS = $(AM_CPPFLAGS)
-udisks_helper_change_filesystem_label_LDADD = $(GLIB_LIBS)
-
-udisks_helper_ata_smart_selftest_SOURCES = job-shared.h job-ata-smart-selftest.c
-udisks_helper_ata_smart_selftest_CPPFLAGS = $(AM_CPPFLAGS) $(LIBATASMART_CFLAGS) $(GLIB_CFLAGS)
-udisks_helper_ata_smart_selftest_LDADD = $(LIBATASMART_LIBS) $(GLIB_LIBS)
-
-udisks_helper_ata_smart_collect_SOURCES = job-ata-smart-collect.c
-udisks_helper_ata_smart_collect_CPPFLAGS = $(AM_CPPFLAGS) $(LIBATASMART_CFLAGS) $(GLIB_CFLAGS)
-udisks_helper_ata_smart_collect_LDADD = $(LIBATASMART_LIBS) $(GLIB_LIBS)
-
-udisks_helper_linux_md_remove_component_SOURCES = job-shared.h job-linux-md-remove-component.c
-udisks_helper_linux_md_remove_component_CPPFLAGS = $(AM_CPPFLAGS)
-udisks_helper_linux_md_remove_component_LDADD = $(GLIB_LIBS)
-
-udisks_helper_fstab_mounter_SOURCES = job-shared.h job-fstab-mounter.c
-udisks_helper_fstab_mounter_CPPFLAGS = $(AM_CPPFLAGS)
-udisks_helper_fstab_mounter_LDADD = $(GLIB_LIBS)
-
-udisks_helper_drive_detach_SOURCES = job-shared.h job-drive-detach.c
-udisks_helper_drive_detach_CPPFLAGS = $(AM_CPPFLAGS) $(LIBUDEV_CFLAGS) $(SGUTILS_CFLAGS)
-udisks_helper_drive_detach_LDADD = $(LIBUDEV_LIBS) $(SGUTILS_LIBS) $(GLIB_LIBS)
-
-udisks_helper_linux_md_check_SOURCES = job-shared.h job-linux-md-check.c
-udisks_helper_linux_md_check_CPPFLAGS = $(AM_CPPFLAGS)
-udisks_helper_linux_md_check_LDADD = $(GLIB_LIBS)
-
-udisks_helper_drive_poll_SOURCES = job-shared.h job-drive-poll.c
-udisks_helper_drive_poll_CPPFLAGS = $(AM_CPPFLAGS)
-udisks_helper_drive_poll_LDADD = $(GLIB_LIBS)
-
-udisks_helper_drive_benchmark_SOURCES = job-drive-benchmark.c
-udisks_helper_drive_benchmark_CPPFLAGS = $(AM_CPPFLAGS)
-udisks_helper_drive_benchmark_LDADD = $(GLIB_LIBS)
-
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2009 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include <glib.h>
-#include <atasmart.h>
-
-static void
-usage (void)
-{
- fprintf (stderr, "incorrect usage\n");
-}
-
-int
-main (int argc,
- char *argv[])
-{
- int ret;
- const char *device;
- SkDisk *d;
- SkBool smart_is_available;
- SkBool awake;
- gboolean nowakeup;
- const void *blob;
- size_t blob_size;
- gchar *encoded_blob;
-
- d = NULL;
- ret = 1;
-
- if (argc != 3)
- {
- usage ();
- goto out;
- }
-
- device = argv[1];
-
- nowakeup = atoi (argv[2]);
-
- if (sk_disk_open (device, &d) != 0)
- {
- g_printerr ("Failed to open disk %s: %m\n", device);
- goto out;
- }
-
- if (sk_disk_check_sleep_mode (d, &awake) != 0)
- {
- g_printerr ("Failed to check if disk %s is awake: %m\n", device);
- goto out;
- }
-
- /* don't wake up disk unless specically asked to */
- if (nowakeup && !awake)
- {
- g_printerr ("Disk %s is asleep and nowakeup option was passed\n", device);
- ret = 2;
- goto out;
- }
-
- if (sk_disk_smart_is_available (d, &smart_is_available) != 0)
- {
- g_printerr ("Failed to determine if smart is available for %s: %m\n", device);
- goto out;
- }
-
- /* main smart data */
- if (sk_disk_smart_read_data (d) != 0)
- {
- g_printerr ("Failed to read smart data for %s: %m\n", device);
- goto out;
- }
-
- if (sk_disk_get_blob (d, &blob, &blob_size) != 0)
- {
- g_printerr ("Failed to read smart data for %s: %m\n", device);
- goto out;
- }
-
- encoded_blob = g_base64_encode ((const guchar *) blob, (gsize) blob_size);
- g_print ("%s\n", encoded_blob);
- g_free (encoded_blob);
-
- ret = 0;
-
- out:
-
- if (d != NULL)
- sk_disk_free (d);
- return ret;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2009 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <glib.h>
-#include <atasmart.h>
-
-static void
-usage (void)
-{
- g_printerr ("incorrect usage\n");
-}
-
-static const gchar *device;
-static gboolean cancelled = FALSE;
-
-static void
-sigterm_handler (int signum)
-{
- cancelled = TRUE;
-}
-
-int
-main (int argc,
- char *argv[])
-{
- int ret;
- SkDisk *d;
- SkBool smart_is_available;
- SkSmartSelfTest test;
-
- d = NULL;
- ret = 1;
-
- if (argc != 3)
- {
- usage ();
- goto out;
- }
-
- device = argv[1];
-
- if (strcmp (argv[2], "short") == 0)
- {
- test = SK_SMART_SELF_TEST_SHORT;
- }
- else if (strcmp (argv[2], "extended") == 0)
- {
- test = SK_SMART_SELF_TEST_EXTENDED;
- }
- else if (strcmp (argv[2], "conveyance") == 0)
- {
- test = SK_SMART_SELF_TEST_CONVEYANCE;
- }
- else
- {
- g_printerr ("Unknown test '%s'\n", argv[2]);
- goto out;
- }
-
- if (sk_disk_open (device, &d) != 0)
- {
- g_printerr ("Failed to open disk %s: %s\n", device, strerror (errno));
- goto out;
- }
-
- if (sk_disk_smart_is_available (d, &smart_is_available) != 0)
- {
- g_printerr ("Failed to determine if smart is available for %s: %s\n", device, strerror (errno));
- goto out;
- }
-
- /* if the user cancels, catch that and abort the test */
- signal (SIGTERM, sigterm_handler);
-
- /* progress at 0% initially */
- g_print ("udisks-helper-progress: 0\n");
-
- /* start the test */
- if (sk_disk_smart_self_test (d, test) != 0)
- {
- g_printerr ("Error initiating test on disk %s: %s\n", device, strerror (errno));
- goto out;
- }
-
- /* poll for completion */
- while (TRUE && !cancelled)
- {
- const SkSmartParsedData *data;
-
- sleep (2);
-
- if (sk_disk_smart_read_data (d) != 0)
- {
- g_printerr ("Failed to read smart data for %s: %s\n", device, strerror (errno));
- goto out;
- }
- if (sk_disk_smart_parse (d, &data) != 0)
- {
- g_printerr ("Failed to parse smart data for %s: %s\n", device, strerror (errno));
- goto out;
- }
-
- if (data->self_test_execution_status != SK_SMART_SELF_TEST_EXECUTION_STATUS_INPROGRESS)
- break;
-
- /* update progress */
- g_print ("udisks-helper-progress: %d\n", 100 - data->self_test_execution_percent_remaining);
- }
-
- /* abort test if cancelled */
- if (cancelled)
- {
- if (sk_disk_smart_self_test (d, SK_SMART_SELF_TEST_ABORT) != 0)
- {
- g_printerr ("Error cancelling test on disk %s: %s\n", device, strerror (errno));
- goto out;
- }
- }
-
- ret = 0;
-
- out:
- if (d != NULL)
- sk_disk_free (d);
- return ret;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#define _LARGEFILE64_SOURCE
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/wait.h>
-
-#include <glib.h>
-
-#include "job-shared.h"
-
-int
-main (int argc,
- char **argv)
-{
- int ret;
- int exit_status;
- GError *error;
- const char *device;
- const char *fstype;
- char *command_line;
- char *standard_error;
- char *new_label;
-
- ret = 1;
- command_line = NULL;
- standard_error = NULL;
- new_label = NULL;
-
- if (argc != 4)
- {
- g_printerr ("wrong usage\n");
- goto out;
- }
- device = argv[1];
- fstype = argv[2];
- new_label = g_strdup (argv[3]);
-
- if (strcmp (fstype, "ext2") == 0 || strcmp (fstype, "ext3") == 0 || strcmp (fstype, "ext4") == 0)
- {
- if (!validate_and_escape_label (&new_label, 16))
- goto out;
- command_line = g_strdup_printf ("e2label %s \"%s\"", device, new_label);
- }
- else if (strcmp (fstype, "xfs") == 0)
- {
- if (!validate_and_escape_label (&new_label, 12))
- goto out;
- if (strlen (new_label) == 0)
- command_line = g_strdup_printf ("xfs_admin -L -- %s", device);
- else
- command_line = g_strdup_printf ("xfs_admin -L \"%s\" %s", new_label, device);
-
- }
- else if (strcmp (fstype, "reiserfs") == 0)
- {
- if (!validate_and_escape_label (&new_label, 16))
- goto out;
- command_line = g_strdup_printf ("reiserfstune -l \"%s\" %s", new_label, device);
- }
- else if (strcmp (fstype, "vfat") == 0)
- {
- if (!validate_and_escape_label (&new_label, 254))
- goto out;
- g_setenv ("MTOOLS_SKIP_CHECK", "1", TRUE);
- if (strlen (new_label) == 0)
- command_line = g_strdup_printf ("mlabel -c -i %s ::", device);
- else
- command_line = g_strdup_printf ("mlabel -i %s \"::%s\"", device, new_label);
-
- }
- else if (strcmp (fstype, "ntfs") == 0)
- {
- command_line = g_strdup_printf ("ntfslabel %s \"%s\"", device, new_label);
- }
- else
- {
- g_printerr ("fstype %s not supported\n", fstype);
- goto out;
- }
-
- if (command_line != NULL)
- {
- error = NULL;
- if (!g_spawn_command_line_sync (command_line, NULL, &standard_error, &exit_status, &error))
- {
- g_printerr ("cannot spawn '%s': %s\n", command_line, error->message);
- g_error_free (error);
- ret = 3; /* indicate FilesystemToolsMissing error */
- goto out;
- }
- if (WEXITSTATUS (exit_status) != 0)
- {
- g_printerr ("helper failed with:\n%s", standard_error);
- goto out;
- }
- }
-
- ret = 0;
-
- out:
- g_free (new_label);
- g_free (standard_error);
- g_free (command_line);
- return ret;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#define _LARGEFILE64_SOURCE
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/wait.h>
-
-#include <glib.h>
-
-#include "job-shared.h"
-#include "partutil.h"
-
-int
-main (int argc,
- char **argv)
-{
- int ret;
- const char *device;
- const char *scheme;
- char **options;
- int n;
- PartitionScheme pscheme;
- gboolean no_partition_table;
-
- ret = 1;
- no_partition_table = FALSE;
- pscheme = PART_TYPE_MSDOS;
-
- if (argc < 3)
- {
- g_printerr ("wrong usage\n");
- goto out;
- }
- device = argv[1];
- scheme = argv[2];
- options = argv + 3;
-
- for (n = 0; options[n] != NULL; n++)
- {
- g_printerr ("option %s not supported\n", options[n]);
- goto out;
- }
-
- if (strcmp (scheme, "mbr") == 0)
- {
- pscheme = PART_TYPE_MSDOS;
- }
- else if (strcmp (scheme, "gpt") == 0)
- {
- pscheme = PART_TYPE_GPT;
- }
- else if (strcmp (scheme, "apm") == 0)
- {
- pscheme = PART_TYPE_APPLE;
- }
- else if (strcmp (scheme, "none") == 0)
- {
- no_partition_table = TRUE;
- }
- else
- {
- g_printerr ("partitioning scheme %s not supported\n", scheme);
- goto out;
- }
-
- /* scrub signatures */
- if (!scrub_signatures (device, 0, 0))
- goto out;
-
- if (no_partition_table)
- {
- ret = 0;
- }
- else
- {
- if (part_create_partition_table ((char *) device, pscheme))
- ret = 0;
- }
-
- /* tell kernel reread partition table (but only if we are a kernel partition) */
- if (!g_str_has_prefix (device, "/dev/mapper/mpath"))
- {
- if (!reread_partition_table (device))
- {
- ret = 1;
- goto out;
- }
- }
-
- out:
- return ret;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#define _LARGEFILE64_SOURCE
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/wait.h>
-#include <linux/blkpg.h>
-
-#include <glib.h>
-#include <gudev/gudev.h>
-
-#include "job-shared.h"
-#include "partutil.h"
-
-int
-main (int argc,
- char **argv)
-{
- int n;
- int ret;
- const char *device;
- char **options;
- char *label;
- char *type;
- char *flags_as_string;
- char **flags;
- guint64 offset;
- guint64 size;
- guint64 out_start;
- guint64 out_size;
- guint out_num;
- char *endp;
-
- ret = 1;
- flags = NULL;
-
- if (argc < 7)
- {
- g_printerr ("wrong usage\n");
- goto out;
- }
- device = argv[1];
- offset = strtoll (argv[2], &endp, 10);
- if (*endp != '\0')
- {
- g_printerr ("malformed offset '%s'\n", argv[2]);
- goto out;
- }
- size = strtoll (argv[3], &endp, 10);
- if (*endp != '\0')
- {
- g_printerr ("malformed size '%s'\n", argv[3]);
- goto out;
- }
- type = argv[4];
- label = argv[5];
- flags_as_string = argv[6];
- options = argv + 7;
-
- flags = g_strsplit (flags_as_string, ",", 0);
-
- /* we trust the caller have verified that the given slice doesn't overlap
- * with existing partitions
- */
-
- g_print ("type: '%s'\n", type);
- g_print ("label: '%s'\n", label);
- g_print ("flags_as_string: '%s'\n", flags_as_string);
-
- /* don't ask libparted to poke the kernel - it won't work if other partitions are mounted/busy */
- if (part_add_partition ((char *) device,
- offset,
- size,
- &out_start,
- &out_size,
- &out_num,
- type,
- strlen (label) > 0 ? label : NULL,
- flags,
- -1,
- -1,
- FALSE))
- {
- gint fd;
- struct blkpg_ioctl_arg a;
- struct blkpg_partition p;
-
- /* now clear out file system signatures in the newly created
- * partition... Unless it's an extended partition!
- */
- n = strtoll (type, &endp, 0);
- if (*endp == '\0' && (n == 0x05 || n == 0x0f || n == 0x85))
- {
- /* do nothing */
- }
- else
- {
- if (!scrub_signatures (device, out_start, out_size))
- {
- g_printerr ("Cannot scrub filesystem signatures at "
- "offset=%" G_GINT64_FORMAT " and size=%" G_GINT64_FORMAT "\n",
- out_start, out_size);
- goto out;
- }
- }
-
- /* OK, now tell the kernel about the newly added partition (but only if we are a kernel partition) */
- if (!g_str_has_prefix (device, "/dev/mapper/mpath"))
- {
- fd = open (device, O_RDONLY);
- if (fd < 0)
- {
- g_printerr ("Cannot open %s: %m\n", device);
- goto out;
- }
- memset (&a, '\0', sizeof(struct blkpg_ioctl_arg));
- memset (&p, '\0', sizeof(struct blkpg_partition));
- p.pno = out_num;
- p.start = out_start;
- p.length = out_size;
- a.op = BLKPG_ADD_PARTITION;
- a.datalen = sizeof(p);
- a.data = &p;
- if (ioctl (fd, BLKPG, &a) == -1)
- {
- g_printerr ("Error doing BLKPG ioctl with BLKPG_ADD_PARTITION for partition %d "
- "of size %" G_GUINT64_FORMAT " at offset %" G_GUINT64_FORMAT " on %s: %m\n",
- out_num,
- out_start,
- out_size,
- device);
- close (fd);
- goto out;
- }
- close (fd);
- }
-
- /* send the start and size back to the daemon - it needs to know, to
- * wait for the created partition, because the partition may not have
- * been created exactly where it was requested....
- */
- g_printerr ("job-create-partition-offset: %" G_GINT64_FORMAT "\n", out_start);
- g_printerr ("job-create-partition-size: %" G_GINT64_FORMAT "\n", out_size);
-
- ret = 0;
- }
-
- out:
- g_strfreev (flags);
- return ret;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#define _LARGEFILE64_SOURCE
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/wait.h>
-#include <linux/blkpg.h>
-
-#include <glib.h>
-
-#include "job-shared.h"
-#include "partutil.h"
-
-int
-main (int argc,
- char **argv)
-{
- int ret;
- const char *device;
- const char *partition_device;
- char **options;
- int n;
- guint64 offset;
- guint64 size;
- int part_number;
- char *endp;
-
- ret = 1;
-
- if (argc < 5)
- {
- g_printerr ("wrong usage\n");
- goto out;
- }
- device = argv[1];
- partition_device = argv[2];
- offset = strtoll (argv[3], &endp, 10);
- if (*endp != '\0')
- {
- g_printerr ("malformed offset '%s'\n", argv[3]);
- goto out;
- }
- size = strtoll (argv[4], &endp, 10);
- if (*endp != '\0')
- {
- g_printerr ("malformed size '%s'\n", argv[4]);
- goto out;
- }
- part_number = strtol (argv[5], &endp, 10);
- if (*endp != '\0')
- {
- g_printerr ("malformed partition number '%s'\n", argv[5]);
- goto out;
- }
-
- options = argv + 6;
-
- for (n = 0; options[n] != NULL; n++)
- {
- g_printerr ("option %s not supported\n", options[n]);
- goto out;
- }
-
- gboolean is_kernel_partition;
- is_kernel_partition = !g_str_has_prefix (device, "/dev/mapper/mpath");
-
- /* don't ask libparted to poke the kernel - it won't work if other
- * partitions are mounted/busy (unless it's not a kernel partition)
- */
- if (part_del_partition ((char *) device,
- offset,
- is_kernel_partition ? FALSE : TRUE))
- {
- /* now, ask the kernel to delete the partition (but only if we are a kernel partition) */
- if (is_kernel_partition)
- {
- gint fd;
- struct blkpg_ioctl_arg a;
- struct blkpg_partition p;
-
- fd = open (device, O_RDONLY);
- if (fd < 0)
- {
- g_printerr ("Cannot open %s: %m\n", device);
- goto out;
- }
- memset (&a, '\0', sizeof(struct blkpg_ioctl_arg));
- memset (&p, '\0', sizeof(struct blkpg_partition));
- p.pno = part_number;
- a.op = BLKPG_DEL_PARTITION;
- a.datalen = sizeof(p);
- a.data = &p;
- if (ioctl (fd, BLKPG, &a) == -1)
- {
- g_printerr ("Error doing BLKPG ioctl with BLKPG_DEL_PARTITION for partition %d on %s: %m\n",
- part_number,
- device);
- close (fd);
- goto out;
- }
- close (fd);
- }
-
- /* zero the contents of what was the _partition_
- *
- *... but only after removing it from the partition table
- * (since it may contain meta data if it's an extended partition)
- */
- /* scrub signatures */
- if (!scrub_signatures (device, offset, size))
- {
- g_printerr ("Cannot scrub filesystem signatures at "
- "offset=%" G_GINT64_FORMAT " and size=%" G_GINT64_FORMAT "\n",
- offset, size);
- }
- else
- {
- ret = 0;
- }
- }
-
- out:
- return ret;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2009 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#define _GNU_SOURCE /* for O_DIRECT */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <linux/fs.h>
-#include <fcntl.h>
-#include <string.h>
-
-#include <glib.h>
-
-static guchar *buf = NULL;
-static guint64 size = 0;
-static const gchar *device_file = NULL;
-static gint fd = -1;
-static gint page_size = 0;
-static guint64 buffer_size = 0;
-
-static void
-report_progress (gdouble percent,
- guint cur_task,
- guint num_tasks)
-{
- gdouble overall;
- static time_t last_report = 0;
- time_t now;
-
- overall = cur_task * 100.0 / num_tasks;
- overall += percent / num_tasks;
-
- /* only send out progress updates every 2-3 seconds - we don't want to spam
- * the bus and clients with events
- */
- now = time (NULL);
- if (last_report == 0 || now - last_report > 2)
- {
- g_print ("udisks-helper-progress: %f\n", overall);
- last_report = now;
- }
-}
-
-static gboolean
-guesstimate_optimal_buffer_size (guint num_samples)
-{
- GTimeVal begin_time;
- GTimeVal end_time;
- gboolean ret;
- gssize remaining;
- gssize total_read;
- gdouble duration_secs;
- gssize num_read;
-
- /* We don't want the benchmark to take forever. So measure the speed in the start and
- * adjust buffer_size such that doing num_samples reads of buffer_size won't take
- * more than 30 seconds.
- *
- * We do this by checking how long it takes to read buffer_size.
- */
-
- ret = FALSE;
-
- if (lseek (fd, 0, SEEK_SET) == -1)
- {
- g_printerr ("Error seeking to start of disk for %s when guesstimating buffer size: %m\n", device_file);
- goto out;
- }
-
- g_get_current_time (&begin_time);
- remaining = buffer_size;
- total_read = 0;
- while (total_read < remaining)
- {
- num_read = read (fd, buf, remaining - total_read);
-
- if (num_read == 0)
- {
- break;
- }
- else if (num_read < 0)
- {
- g_printerr ("Error reading %" G_GUINT64_FORMAT " bytes at %" G_GSSIZE_FORMAT " from %s "
- "when guesstimating buffer size: %m\n",
- buffer_size,
- (remaining - total_read),
- device_file);
- goto out;
- }
- else
- {
- total_read += num_read;
- }
- }
- g_get_current_time (&end_time);
-
- duration_secs = ((end_time.tv_sec * G_USEC_PER_SEC + end_time.tv_usec) - (begin_time.tv_sec * G_USEC_PER_SEC
- + begin_time.tv_usec)) / ((gdouble) G_USEC_PER_SEC);
-
- /* duration_secs is (approx) the number of seconds needed to do one sample */
- if (duration_secs * num_samples > 30.0)
- {
- guint64 new_buffer_size;
-
- new_buffer_size = buffer_size * 30.0 / (duration_secs * num_samples);
- new_buffer_size &= ~(page_size - 1);
-
- if (new_buffer_size < 1 * 1024 * 1024)
- {
- g_printerr ("Device %s is too slow to benchmark", device_file);
- goto out;
- }
-
- buffer_size = new_buffer_size;
- }
-
- ret = TRUE;
-
- out:
- return ret;
-}
-
-static gboolean
-measure_transfer_rate (guint num_samples,
- guint cur_task,
- guint num_tasks)
-{
- gboolean ret;
- guint n;
- guint64 sample_size;
-
- sample_size = buffer_size;
-
- ret = FALSE;
-
- /* First measure read (or TODO: write) performance across the drive */
- for (n = 0; n < num_samples; n++)
- {
- goffset pos;
- gssize remaining;
- gssize total_read;
- GTimeVal begin_time;
- GTimeVal end_time;
- gdouble duration_secs;
- gssize num_read;
-
- pos = n * size / num_samples;
-
- /* O_DIRECT also only wants to read from page offsets */
- pos &= ~(page_size - 1);
-
- if (lseek64 (fd, pos, SEEK_SET) == -1)
- {
- g_printerr ("Error seeking to position %" G_GOFFSET_FORMAT " for %s: %m\n",
- pos,
- device_file);
- goto out;
- }
-
- /* read a single page - otherwise disk spinup + seek time will pollute the result
- * (ignores error checking since that's done below)
- */
- num_read = read (fd, buf, page_size);
-
- g_get_current_time (&begin_time);
- total_read = 0;
- remaining = sample_size;
- while (total_read < remaining)
- {
- num_read = read (fd, buf, remaining - total_read);
-
- if (num_read == 0)
- {
- break;
- }
- else if (num_read < 0)
- {
- g_printerr ("Error reading %" G_GUINT64_FORMAT " bytes at %" G_GOFFSET_FORMAT " from %s: %m\n",
- sample_size,
- pos + (remaining - total_read),
- device_file);
- goto out;
- }
- else
- {
- total_read += num_read;
- }
-
- }
- g_get_current_time (&end_time);
-
- duration_secs = ((end_time.tv_sec * G_USEC_PER_SEC + end_time.tv_usec) - (begin_time.tv_sec * G_USEC_PER_SEC
- + begin_time.tv_usec)) / ((gdouble) G_USEC_PER_SEC);
-
- g_print ("read_transfer_rate: offset %" G_GOFFSET_FORMAT " rate %f\n",
- pos,
- sample_size / duration_secs);
-
- report_progress (100.0 * n / num_samples, cur_task, num_tasks);
- }
-
- ret = TRUE;
-
- out:
- return ret;
-}
-
-static gboolean
-measure_write_transfer_rate (guint num_samples,
- guint cur_task,
- guint num_tasks)
-{
- gboolean ret;
- guint n;
- guint64 sample_size;
-
- sample_size = buffer_size;
-
- ret = FALSE;
-
- /* First measure read (or TODO: write) performance across the drive */
- for (n = 0; n < num_samples; n++)
- {
- goffset pos;
- gssize remaining;
- gssize total_written;
- GTimeVal begin_time;
- GTimeVal end_time;
- gdouble duration_secs;
- gssize num_written;
-
- pos = n * size / num_samples;
-
- /* O_DIRECT also only wants to read from page offsets */
- pos &= ~(page_size - 1);
-
- if (lseek64 (fd, pos, SEEK_SET) == -1)
- {
- g_printerr ("Error seeking to position %" G_GOFFSET_FORMAT " for %s: %m\n",
- pos,
- device_file);
- goto out;
- }
-
- /* read a single page - otherwise disk spinup + seek time will pollute the result
- * (ignores error checking since that's done below)
- */
- num_written = read (fd, buf, page_size);
-
- g_get_current_time (&begin_time);
- total_written = 0;
- remaining = sample_size;
- while (total_written < remaining)
- {
- num_written = write (fd, buf, remaining - total_written);
-
- if (num_written == 0)
- {
- break;
- }
- else if (num_written < 0)
- {
- g_printerr ("Error writing %" G_GUINT64_FORMAT " bytes at %" G_GOFFSET_FORMAT " to %s: %m\n",
- sample_size,
- pos + (remaining - total_written),
- device_file);
- goto out;
- }
- else
- {
- total_written += num_written;
- }
-
- }
-
- if (fsync (fd) != 0)
- {
- g_printerr ("Error fsync()'ing after writing at %" G_GOFFSET_FORMAT " to %s: %m\n",
- pos + (remaining - total_written),
- device_file);
- goto out;
- }
-
- g_get_current_time (&end_time);
-
- duration_secs = ((end_time.tv_sec * G_USEC_PER_SEC + end_time.tv_usec) - (begin_time.tv_sec * G_USEC_PER_SEC
- + begin_time.tv_usec)) / ((gdouble) G_USEC_PER_SEC);
-
- g_print ("write_transfer_rate: offset %" G_GOFFSET_FORMAT " rate %f\n",
- pos,
- sample_size / duration_secs);
-
- report_progress (100.0 * n / num_samples, cur_task, num_tasks);
- }
-
- ret = TRUE;
-
- out:
- return ret;
-}
-
-static gboolean
-measure_access_time (guint num_samples,
- guint cur_task,
- guint num_tasks)
-{
- gboolean ret;
- guint n;
- GRand *rand;
- GTimeVal begin_time;
- GTimeVal end_time;
- gdouble duration_secs;
-
- ret = FALSE;
-
- /* we want this to be deterministic (per size) to make benchmarks repeatable */
- rand = g_rand_new_with_seed (42);
-
- for (n = 0; n < num_samples; n++)
- {
- guint64 pos;
-
- pos = (guint64) g_rand_double_range (rand, 0, (gdouble) (size - page_size));
- pos &= ~(page_size - 1);
-
- g_get_current_time (&begin_time);
- if (lseek64 (fd, pos, SEEK_SET) == -1)
- {
- g_printerr ("Error seeking to position %" G_GUINT64_FORMAT " for %s: %m\n",
- pos,
- device_file);
- goto out;
- }
- if (read (fd, buf, page_size) < 0)
- {
- g_printerr ("Error reading %d bytes at %" G_GUINT64_FORMAT " from %s: %m\n",
- page_size,
- pos,
- device_file);
- goto out;
- }
- g_get_current_time (&end_time);
-
- duration_secs = ((end_time.tv_sec * G_USEC_PER_SEC + end_time.tv_usec) - (begin_time.tv_sec * G_USEC_PER_SEC
- + begin_time.tv_usec)) / ((gdouble) G_USEC_PER_SEC);
-
- g_print ("access_time: offset %" G_GUINT64_FORMAT " time %f\n",
- pos,
- duration_secs);
-
- report_progress (100.0 * n / num_samples, cur_task, num_tasks);
- }
-
- ret = TRUE;
-
- out:
- if (rand != NULL)
- g_rand_free (rand);
-
- return ret;
-}
-
-int
-main (int argc,
- char *argv[])
-{
- gint ret;
- guchar *buf_unaligned;
- guint num_transfer_rate_samples;
- guint num_access_time_samples;
- gboolean do_write_benchmark;
- guint cur_task;
- guint num_tasks;
-
- ret = 1;
- fd = -1;
- buf_unaligned = NULL;
-
- if (argc != 3)
- {
- g_printerr ("incorrect usage\n");
- goto out;
- }
-
- /* TODO: should these be configurable? */
- num_transfer_rate_samples = 200;
- num_access_time_samples = 1000;
-
- device_file = argv[1];
-
- do_write_benchmark = atoi (argv[2]);
-
- if (do_write_benchmark)
- {
- fd = open (device_file, O_RDWR | O_DIRECT);
- }
- else
- {
- fd = open (device_file, O_RDONLY | O_DIRECT);
- }
- if (fd < 0)
- {
- g_printerr ("Error opening %s: %m\n", device_file);
- goto out;
- }
-
- if (ioctl (fd, BLKGETSIZE64, &size) != 0)
- {
- g_printerr ("Error finding size of %s: %m\n", device_file);
- goto out;
- }
-
- page_size = sysconf (_SC_PAGESIZE);
- if (page_size < 1)
- {
- g_printerr ("Error getting page size: %m\n");
- goto out;
- }
-
- /* upper bound for buffer size */
- buffer_size = 100 * 1024 * 1024;
-
- buf_unaligned = g_new0 (guchar, buffer_size + page_size);
-
- /* O_DIRECT needs a page aligned buffer */
- buf = (guchar*) (((gintptr) (buf_unaligned + page_size)) & (~(page_size - 1)));
-
- g_print ("udisks-helper-progress: 0.0\n");
-
- if (!guesstimate_optimal_buffer_size (num_transfer_rate_samples))
- goto out;
-
- /* TODO: report back chosen buffer_size? g_print ("buffer_size: %" G_GUINT64_FORMAT "\n", buffer_size); */
-
- cur_task = 0;
- if (do_write_benchmark)
- num_tasks = 3;
- else
- num_tasks = 2;
-
- if (!measure_transfer_rate (num_transfer_rate_samples, cur_task++, num_tasks))
- goto out;
-
- if (do_write_benchmark)
- {
- if (!measure_write_transfer_rate (num_transfer_rate_samples, cur_task++, num_tasks))
- goto out;
- }
-
- if (!measure_access_time (num_access_time_samples, cur_task++, num_tasks))
- goto out;
-
- ret = 0;
-
- out:
- if (fd != -1)
- close (fd);
- g_free (buf_unaligned);
-
- return ret;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-*/
-/*
- * Copyright (C) 2009 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include <scsi/sg_lib.h>
-#include <scsi/sg_cmds.h>
-
-#include <libudev.h>
-
-#include <glib.h>
-
-static void
-usage (void)
-{
- g_printerr ("incorrect usage\n");
-}
-
-static gboolean
-sysfs_exists (const gchar *path,
- const gchar *file)
-{
- struct stat statbuf;
- gchar *s;
- gboolean ret;
-
- ret = FALSE;
-
- s = g_strdup_printf ("%s/%s", path, file);
- if (stat (s, &statbuf) == 0)
- ret = TRUE;
- g_free (s);
-
- return ret;
-}
-
-static gboolean
-sysfs_write (const gchar *path,
- const gchar *file,
- const gchar *value)
-{
- FILE *f;
- gchar *s;
- gboolean ret;
-
- ret = FALSE;
- s = NULL;
- f = NULL;
-
- s = g_strdup_printf ("%s/%s", path, file);
- f = fopen (s, "w");
- if (f == NULL)
- {
- g_printerr ("FAILED: Cannot open %s for writing: %m\n", s);
- goto out;
- }
-
- if (fwrite (value, sizeof(char), strlen (value), f) < strlen (value))
- {
- g_printerr ("FAILED: Error writing %s to %s: %m\n", value, s);
- goto out;
- }
-
- ret = TRUE;
-
- out:
- g_free (s);
-
- if (f != NULL)
- fclose (f);
-
- return ret;
-}
-
-int
-main (int argc,
- char *argv[])
-{
- int ret;
- int sg_fd;
- const gchar *device;
- struct udev *udev;
- struct udev_device *udevice;
- struct udev_device *udevice_usb_interface;
- struct udev_device *udevice_usb_device;
- gchar *unbind_path;
- gchar *power_level_path;
- gchar *usb_interface_name;
- struct stat statbuf;
- const char *bNumInterfaces;
- gchar *endp;
- int num_interfaces;
-
- udev = NULL;
- udevice = NULL;
- udevice_usb_interface = NULL;
- udevice_usb_device = NULL;
- usb_interface_name = NULL;
- unbind_path = NULL;
- power_level_path = NULL;
-
- ret = 1;
- sg_fd = -1;
-
- if (argc != 2)
- {
- usage ();
- goto out;
- }
-
- device = argv[1];
-
- if (stat (device, &statbuf) != 0)
- {
- g_printerr ("Error statting %s: %m\n", device);
- goto out;
- }
- if (statbuf.st_rdev == 0)
- {
- g_printerr ("%s is not a special device file\n", device);
- goto out;
- }
-
- udev = udev_new ();
- if (udev == NULL)
- {
- g_printerr ("Error initializing libudev: %m\n");
- goto out;
- }
-
- udevice = udev_device_new_from_devnum (udev, 'b', statbuf.st_rdev);
- if (udevice == NULL)
- {
- g_printerr ("No udev device for device %s (devnum 0x%08x): %m\n", device, (gint) statbuf.st_rdev);
- goto out;
- }
- udevice_usb_interface = udev_device_get_parent_with_subsystem_devtype (udevice, "usb", "usb_interface");
- if (udevice_usb_interface == NULL)
- {
- g_printerr ("No usb parent interface for %s: %m\n", device);
- goto out;
- }
- udevice_usb_device = udev_device_get_parent_with_subsystem_devtype (udevice, "usb", "usb_device");
- if (udevice_usb_device == NULL)
- {
- g_printerr ("No usb parent device for %s: %m\n", device);
- goto out;
- }
-
- g_printerr ("Detaching device %s\nUSB device: %s)\n",
- device,
- udev_device_get_syspath (udevice_usb_device));
-
- sg_fd = sg_cmds_open_device (device, 1 /* read_only */, 1);
- if (sg_fd < 0)
- {
- g_printerr ("Cannot open %s: %m\n", device);
- goto out;
- }
-
- g_printerr ("SYNCHRONIZE CACHE: ");
- if (sg_ll_sync_cache_10 (sg_fd, 0, /* sync_nv */
- 0, /* immed */
- 0, /* group */
- 0, /* lba */
- 0, /* count */
- 1, /* noisy */
- 0 /* verbose */
- ) != 0)
- {
- g_printerr ("FAILED: %m\n");
- /* this is not a catastrophe, carry on */
- g_printerr ("(Continuing despite SYNCHRONIZE CACHE failure.)\n");
- }
- else
- {
- g_printerr ("OK\n");
- }
-
- g_printerr ("STOP UNIT: ");
- if (sg_ll_start_stop_unit (sg_fd, 0, /* immed */
- 0, /* pc_mod__fl_num */
- 0, /* power_cond */
- 0, /* noflush__fl */
- 0, /* loej */
- 0, /* start */
- 1, /* noisy */
- 0 /* verbose */
- ) != 0)
- {
- g_printerr ("FAILED: %m\n");
- goto out;
- }
- else
- {
- g_printerr ("OK\n");
- }
-
- /* OK, close the device */
- sg_cmds_close_device (sg_fd);
- sg_fd = -1;
-
- /* unbind the mass storage driver (e.g. usb-storage) */
- usb_interface_name = g_path_get_basename (udev_device_get_devpath (udevice_usb_interface));
- g_printerr ("Unbinding USB interface driver: ");
- if (!sysfs_write (udev_device_get_syspath (udevice_usb_interface),
- "driver/unbind",
- usb_interface_name))
- goto out;
- g_printerr ("OK\n");
-
- bNumInterfaces = udev_device_get_sysattr_value (udevice_usb_device, "bNumInterfaces");
- num_interfaces = strtol (bNumInterfaces, &endp, 0);
- if (endp != NULL && num_interfaces == 1)
- {
- g_printerr ("Suspending USB device: ");
- if (!sysfs_write (udev_device_get_syspath (udevice_usb_device), "power/level", "auto") ||
- !sysfs_write (udev_device_get_syspath (udevice_usb_device), "power/autosuspend", "0"))
- goto out;
- g_printerr ("OK\n");
-
- /* the remove file is pretty recent (commit as1297, Dec 2009) */
- if (sysfs_exists (udev_device_get_syspath (udevice_usb_device), "remove"))
- {
- g_printerr ("Disabling USB port for device: ");
- if (!sysfs_write (udev_device_get_syspath (udevice_usb_device), "remove", "1"))
- goto out;
- g_printerr ("OK\n");
- }
- }
- else
- {
- g_printerr ("Not powering down device since multiple USB interfaces exist.\n");
- }
-
- ret = 0;
-
- out:
- g_free (usb_interface_name);
- g_free (unbind_path);
- g_free (power_level_path);
- if (sg_fd > 0)
- sg_cmds_close_device (sg_fd);
- if (udevice != NULL)
- udev_device_unref (udevice);
- if (udev != NULL)
- udev_unref (udev);
- return ret;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2009 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <string.h>
-
-#include <glib.h>
-
-static void
-usage (void)
-{
- g_printerr ("incorrect usage\n");
-}
-
-int
-main (int argc,
- char *argv[])
-{
- int ret;
- const gchar *device_file;
- gboolean is_cdrom;
- int fd, fd2;
-
- ret = 1;
-
- if (argc != 2)
- {
- usage ();
- goto out;
- }
-
- device_file = argv[1];
-
- /* the device file is the canonical device file from udev */
- is_cdrom = (g_str_has_prefix (device_file, "/dev/sr") || g_str_has_prefix (device_file, "/dev/scd"));
-
- if (is_cdrom)
- {
- /* optical drives need special care
- *
- * - use O_NONBLOCK to avoid closing the door
- * - use O_EXCL to avoid interferring with cd burning software / audio playback / etc
- */
- fd = open (device_file, O_RDONLY | O_NONBLOCK | O_EXCL);
- if (fd != -1)
- close (fd);
- }
- else
- {
- fd = open (device_file, O_RDONLY);
- fd2 = open (device_file, O_RDONLY | O_NONBLOCK);
- if (fd != -1)
- close (fd);
- if (fd2 != -1)
- close (fd2);
- }
-
- ret = 0;
-
- out:
- return ret;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#define _LARGEFILE64_SOURCE
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/wait.h>
-
-#include <glib.h>
-
-#include "job-shared.h"
-
-int
-main (int argc,
- char **argv)
-{
- int ret;
- int exit_status;
- GError *error;
- const char *action;
- const char *device;
- uid_t uid;
- char *command_line;
- char *standard_error;
- char *endp;
- gboolean do_mount;
- gboolean do_unmount;
- gboolean do_force_unmount;
-
- ret = 1;
- command_line = NULL;
- standard_error = NULL;
- do_mount = FALSE;
- do_unmount = FALSE;
- do_force_unmount = FALSE;
-
- if (argc != 4)
- {
- g_printerr ("wrong usage: expected 3 parameters, got %d\n", argc);
- goto out;
- }
- action = argv[1];
- device = argv[2];
- uid = strtol (argv[3], &endp, 10);
- if (endp == NULL || *endp != '\0')
- {
- g_printerr ("wrong usage: malformed uid '%s'\n", argv[3]);
- goto out;
- }
- if (strcmp (action, "mount") == 0)
- {
- do_mount = TRUE;
- }
- else if (strcmp (action, "unmount") == 0)
- {
- do_unmount = TRUE;
- }
- else if (strcmp (action, "force_unmount") == 0)
- {
- do_force_unmount = TRUE;
- }
- else
- {
- g_printerr ("wrong usage: malformed action '%s'\n", action);
- goto out;
- }
-
- /* become the user; right now we are uid 0.. so after the setuid() call we
- * can never gain root again
- */
- if (uid != 0)
- {
- if (setuid (uid) != 0)
- {
- g_printerr ("cannot switch to uid %d: %m\n", uid);
- goto out;
- }
- }
-
- if (do_mount)
- {
- command_line = g_strdup_printf ("mount %s", device);
- }
- else if (do_unmount)
- {
- command_line = g_strdup_printf ("umount %s", device);
- }
- else if (do_force_unmount)
- {
- command_line = g_strdup_printf ("umount -l %s", device);
- }
- else
- {
- g_assert_not_reached ();
- }
-
- error = NULL;
- if (!g_spawn_command_line_sync (command_line, NULL, &standard_error, &exit_status, &error))
- {
- g_printerr ("cannot spawn '%s': %s\n", command_line, error->message);
- g_error_free (error);
- goto out;
- }
- if (WEXITSTATUS (exit_status) != 0)
- {
- g_printerr ("helper failed with:\n%s", standard_error);
- goto out;
- }
- ret = 0;
-
- out:
- g_free (standard_error);
- g_free (command_line);
- return ret;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#define _LARGEFILE64_SOURCE
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/wait.h>
-#include <signal.h>
-
-#include <glib.h>
-
-#include "job-shared.h"
-
-static gboolean
-sysfs_put_string (const gchar *sysfs_path,
- const gchar *file,
- const gchar *value)
-{
- FILE *f;
- gchar *filename;
- gboolean ret;
-
- ret = FALSE;
- filename = NULL;
-
- filename = g_build_filename (sysfs_path, file, NULL);
- f = fopen (filename, "w");
- if (f == NULL)
- {
- g_printerr ("error opening %s for writing: %m\n", filename);
- goto out;
- }
- else
- {
- if (fputs (value, f) == EOF)
- {
- g_printerr ("error writing '%s' to %s: %m\n", value, filename);
- fclose (f);
- goto out;
- }
- fclose (f);
- }
-
- ret = TRUE;
- out:
- g_free (filename);
- return ret;
-}
-
-static char *
-sysfs_get_string (const gchar *sysfs_path,
- const gchar *file)
-{
- gchar *result;
- gchar *filename;
-
- result = NULL;
- filename = g_build_filename (sysfs_path, file, NULL);
- if (!g_file_get_contents (filename, &result, NULL, NULL))
- {
- result = g_strdup ("");
- }
- g_free (filename);
-
- return result;
-}
-
-static gboolean cancelled = FALSE;
-
-static void
-sigterm_handler (int signum)
-{
- cancelled = TRUE;
-}
-
-int
-main (int argc,
- char **argv)
-{
- gint ret;
- const gchar *device;
- const gchar *sysfs_path;
- gchar *sync_action;
- gboolean repair;
- gchar **options;
- gint n;
-
- ret = 1;
- repair = FALSE;
- sync_action = NULL;
-
- if (argc < 3)
- {
- g_printerr ("wrong usage\n");
- goto out;
- }
- device = argv[1];
- sysfs_path = argv[2];
- options = argv + 3;
-
- for (n = 0; options[n] != NULL; n++)
- {
- if (strcmp (options[n], "repair") == 0)
- {
- repair = TRUE;
- }
- else
- {
- g_printerr ("option %s not supported\n", options[n]);
- goto out;
- }
- }
-
- g_print ("device = '%s'\n", device);
- g_print ("repair = %d\n", repair);
-
- sync_action = sysfs_get_string (sysfs_path, "md/sync_action");
- g_strstrip (sync_action);
- if (g_strcmp0 (sync_action, "idle") != 0)
- {
- g_printerr ("device %s is not idle\n", device);
- goto out;
- }
-
- /* if the user cancels, catch that and make the array idle */
- signal (SIGTERM, sigterm_handler);
-
- if (!sysfs_put_string (sysfs_path, "md/sync_action", repair ? "repair" : "check"))
- {
- goto out;
- }
-
- g_print ("udisks-helper-progress: 0\n");
- while (!cancelled)
- {
- guint64 done;
- guint64 remaining;
- gchar *s;
-
- sleep (2);
-
- sync_action = sysfs_get_string (sysfs_path, "md/sync_action");
- g_strstrip (sync_action);
- if (g_strcmp0 (sync_action, "idle") == 0)
- {
- break;
- }
- g_free (sync_action);
- sync_action = NULL;
-
- s = g_strstrip (sysfs_get_string (sysfs_path, "md/sync_completed"));
- if (sscanf (s, "%" G_GUINT64_FORMAT " / %" G_GUINT64_FORMAT "", &done, &remaining) == 2)
- {
- g_print ("udisks-helper-progress: %d\n", (gint) (100L * done / remaining));
- }
- else
- {
- g_printerr ("Cannot parse md/sync_completed: '%s'", s);
- goto out;
- }
- g_free (s);
- }
-
- if (cancelled)
- {
- sysfs_put_string (sysfs_path, "md/sync_action", "idle");
- goto out;
- }
-
- ret = 0;
-
- out:
- g_free (sync_action);
- return ret;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#define _LARGEFILE64_SOURCE
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/wait.h>
-#include <signal.h>
-
-#include <glib.h>
-
-#include "job-shared.h"
-
-int
-main (int argc,
- char **argv)
-{
- int ret;
- int exit_status;
- GError *error;
- char *command_line;
- char *standard_error;
- char *device;
- char *slave;
- char *erase;
- char **options;
- int n;
-
- ret = 1;
- command_line = NULL;
- standard_error = NULL;
- erase = NULL;
-
- if (argc < 3)
- {
- g_printerr ("wrong usage\n");
- goto out;
- }
- device = argv[1];
- slave = argv[2];
- options = argv + 3;
-
- for (n = 0; options[n] != NULL; n++)
- {
- if (g_str_has_prefix (options[n], "erase="))
- {
- erase = strdup (options[n] + sizeof("erase=") - 1);
- }
- else
- {
- g_printerr ("option %s not supported\n", options[n]);
- goto out;
- }
- }
-
- g_print ("device = '%s'\n", device);
- g_print ("slave = '%s'\n", slave);
- g_print ("erase = '%s'\n", erase);
-
- /* first we fail it... */
- command_line = g_strdup_printf ("mdadm --manage %s --fail %s", device, slave);
-
- error = NULL;
- if (!g_spawn_command_line_sync (command_line, NULL, &standard_error, &exit_status, &error))
- {
- g_printerr ("cannot spawn '%s': %s\n", command_line, error->message);
- g_error_free (error);
- goto out;
- }
- if (WEXITSTATUS (exit_status) != 0)
- {
- g_printerr ("'%s' failed with: '%s'\n", command_line, standard_error);
- goto out;
- }
- g_free (standard_error);
- g_free (command_line);
- standard_error = NULL;
- command_line = NULL;
-
- /* TODO: Seems like a kernel bug that you can't immediately remove a component
- * that you just failed. For now sleeping seems to work.
- */
- sleep (1);
-
- /* ...then we remove it */
- command_line = g_strdup_printf ("mdadm --manage %s --remove %s", device, slave);
-
- error = NULL;
- if (!g_spawn_command_line_sync (command_line, NULL, &standard_error, &exit_status, &error))
- {
- g_printerr ("cannot spawn '%s': %s\n", command_line, error->message);
- g_error_free (error);
- goto out;
- }
- if (WEXITSTATUS (exit_status) != 0)
- {
- g_printerr ("'%s' failed with: '%s'\n", command_line, standard_error);
- goto out;
- }
- g_free (standard_error);
- g_free (command_line);
- standard_error = NULL;
- command_line = NULL;
-
- ret = 0;
-
- out:
- g_free (standard_error);
- g_free (command_line);
- g_free (erase);
- return ret;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#define _LARGEFILE64_SOURCE
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/wait.h>
-#include <sys/mount.h>
-
-#include <glib.h>
-
-#include "job-shared.h"
-
-int
-main (int argc,
- char **argv)
-{
- int fd;
- int ret;
- int exit_status;
- GError *error;
- const char *fstype;
- const char *device;
- char *command_line;
- char *standard_error;
- char **options;
- GString *s;
- char *label;
- int n;
- gboolean is_kernel_partitioned;
- GIOChannel *stdin_channel;
- GPtrArray *options_array;
- char *option;
- gsize option_len;
- char *endp;
- uid_t take_ownership_uid;
- gid_t take_ownership_gid;
-
- ret = 1;
- command_line = NULL;
- standard_error = NULL;
- take_ownership_uid = 0;
- take_ownership_gid = 0;
- label = NULL;
-
- if (argc != 4)
- {
- g_printerr ("wrong usage\n");
- goto out;
- }
- fstype = argv[1];
- device = argv[2];
- is_kernel_partitioned = (strcmp (argv[3], "1") == 0);
-
- options_array = g_ptr_array_new ();
- stdin_channel = g_io_channel_unix_new (0);
- if (stdin_channel == NULL)
- {
- g_printerr ("cannot open stdin\n");
- goto out;
- }
- while (g_io_channel_read_line (stdin_channel, &option, &option_len, NULL, NULL) == G_IO_STATUS_NORMAL)
- {
- option[option_len - 1] = '\0';
- if (strlen (option) == 0)
- break;
- g_ptr_array_add (options_array, option);
- }
- g_io_channel_unref (stdin_channel);
- g_ptr_array_add (options_array, NULL);
- options = (char **) g_ptr_array_free (options_array, FALSE);
-
- if (strcmp (fstype, "vfat") == 0)
- {
-
- /* allow to create an fs on the main block device */
- s = g_string_new ("mkfs.vfat -I");
- for (n = 0; options[n] != NULL; n++)
- {
- if (g_str_has_prefix (options[n], "label="))
- {
- label = strdup (options[n] + sizeof("label=") - 1);
- if (!validate_and_escape_label (&label, 254))
- {
- g_string_free (s, TRUE);
- goto out;
- }
- if (strlen (label) <= 11)
- {
- g_string_append_printf (s, " -n \"%s\"", label);
- g_free (label);
- label = NULL;
- }
- }
- else
- {
- g_printerr ("option %s not supported\n", options[n]);
- goto out;
- }
- }
- g_string_append_printf (s, " %s", device);
- command_line = g_string_free (s, FALSE);
-
- }
- else if (strcmp (fstype, "ext2") == 0 || strcmp (fstype, "ext3") == 0 || strcmp (fstype, "ext4") == 0)
- {
-
- s = g_string_new ("mkfs.");
- g_string_append (s, fstype);
- for (n = 0; options[n] != NULL; n++)
- {
- g_string_append (s, " -F ");
- if (g_str_has_prefix (options[n], "label="))
- {
- label = strdup (options[n] + sizeof("label=") - 1);
- if (!validate_and_escape_label (&label, 16))
- {
- g_string_free (s, TRUE);
- goto out;
- }
- g_string_append_printf (s, " -L \"%s\"", label);
- g_free (label);
- label = NULL;
- }
- else if (g_str_has_prefix (options[n], "take_ownership_uid="))
- {
- take_ownership_uid = strtol (options[n] + sizeof("take_ownership_uid=") - 1, &endp, 10);
- if (endp == NULL || *endp != '\0')
- {
- g_printerr ("option %s is malformed\n", options[n]);
- goto out;
- }
- }
- else if (g_str_has_prefix (options[n], "take_ownership_gid="))
- {
- take_ownership_gid = strtol (options[n] + sizeof("take_ownership_gid=") - 1, &endp, 10);
- if (endp == NULL || *endp != '\0')
- {
- g_printerr ("option %s is malformed\n", options[n]);
- goto out;
- }
- }
- else
- {
- g_printerr ("option %s not supported\n", options[n]);
- goto out;
- }
- }
- g_string_append_printf (s, " %s", device);
- command_line = g_string_free (s, FALSE);
-
- }
- else if (strcmp (fstype, "xfs") == 0)
- {
-
- s = g_string_new ("mkfs.xfs");
- for (n = 0; options[n] != NULL; n++)
- {
- if (g_str_has_prefix (options[n], "label="))
- {
- label = strdup (options[n] + sizeof("label=") - 1);
- if (!validate_and_escape_label (&label, 12))
- {
- g_string_free (s, TRUE);
- goto out;
- }
- g_string_append_printf (s, " -L \"%s\"", label);
- g_free (label);
- label = NULL;
- }
- else if (g_str_has_prefix (options[n], "take_ownership_uid="))
- {
- take_ownership_uid = strtol (options[n] + sizeof("take_ownership_uid=") - 1, &endp, 10);
- if (endp == NULL || *endp != '\0')
- {
- g_printerr ("option %s is malformed\n", options[n]);
- goto out;
- }
- }
- else if (g_str_has_prefix (options[n], "take_ownership_gid="))
- {
- take_ownership_gid = strtol (options[n] + sizeof("take_ownership_gid=") - 1, &endp, 10);
- if (endp == NULL || *endp != '\0')
- {
- g_printerr ("option %s is malformed\n", options[n]);
- goto out;
- }
- }
- else
- {
- g_printerr ("option %s not supported\n", options[n]);
- goto out;
- }
- }
- g_string_append_printf (s, " %s", device);
- command_line = g_string_free (s, FALSE);
-
- }
- else if (strcmp (fstype, "ntfs") == 0)
- {
-
- /* skip zeroing (we do that ourselves) and bad sector checking (will
- * eventually be handled on a higher level)
- */
- s = g_string_new ("mkntfs -f");
- for (n = 0; options[n] != NULL; n++)
- {
- if (g_str_has_prefix (options[n], "label="))
- {
- label = strdup (options[n] + sizeof("label=") - 1);
- if (!validate_and_escape_label (&label, 255))
- {
- g_string_free (s, TRUE);
- goto out;
- }
- g_string_append_printf (s, " -L \"%s\"", label);
- g_free (label);
- label = NULL;
- }
- else
- {
- g_printerr ("option %s not supported\n", options[n]);
- goto out;
- }
- }
- g_string_append_printf (s, " %s", device);
- command_line = g_string_free (s, FALSE);
-
- }
- else if (strcmp (fstype, "reiserfs") == 0)
- {
-
- s = g_string_new ("mkfs.reiserfs -q");
- for (n = 0; options[n] != NULL; n++)
- {
- if (g_str_has_prefix (options[n], "label="))
- {
- label = strdup (options[n] + sizeof("label=") - 1);
- if (!validate_and_escape_label (&label, 16))
- {
- g_string_free (s, TRUE);
- goto out;
- }
- g_string_append_printf (s, " -l \"%s\"", label);
- g_free (label);
- label = NULL;
- }
- else if (g_str_has_prefix (options[n], "take_ownership_uid="))
- {
- take_ownership_uid = strtol (options[n] + sizeof("take_ownership_uid=") - 1, &endp, 10);
- if (endp == NULL || *endp != '\0')
- {
- g_printerr ("option %s is malformed\n", options[n]);
- goto out;
- }
- }
- else if (g_str_has_prefix (options[n], "take_ownership_gid="))
- {
- take_ownership_gid = strtol (options[n] + sizeof("take_ownership_gid=") - 1, &endp, 10);
- if (endp == NULL || *endp != '\0')
- {
- g_printerr ("option %s is malformed\n", options[n]);
- goto out;
- }
- }
- else
- {
- g_printerr ("option %s not supported\n", options[n]);
- goto out;
- }
- }
- g_string_append_printf (s, " %s", device);
- command_line = g_string_free (s, FALSE);
-
- }
- else if (strcmp (fstype, "minix") == 0)
- {
-
- s = g_string_new ("mkfs.minix");
- /* minix does not support labels */
- for (n = 0; options[n] != NULL; n++)
- {
- if (g_str_has_prefix (options[n], "take_ownership_uid="))
- {
- take_ownership_uid = strtol (options[n] + sizeof("take_ownership_uid=") - 1, &endp, 10);
- if (endp == NULL || *endp != '\0')
- {
- g_printerr ("option %s is malformed\n", options[n]);
- goto out;
- }
- }
- else if (g_str_has_prefix (options[n], "take_ownership_gid="))
- {
- take_ownership_gid = strtol (options[n] + sizeof("take_ownership_gid=") - 1, &endp, 10);
- if (endp == NULL || *endp != '\0')
- {
- g_printerr ("option %s is malformed\n", options[n]);
- goto out;
- }
- }
- else
- {
- g_printerr ("option %s not supported\n", options[n]);
- goto out;
- }
- }
- g_string_append_printf (s, " %s", device);
- command_line = g_string_free (s, FALSE);
-
- }
- else if (strcmp (fstype, "swap") == 0)
- {
-
- s = g_string_new ("mkswap");
- for (n = 0; options[n] != NULL; n++)
- {
- if (g_str_has_prefix (options[n], "label="))
- {
- label = strdup (options[n] + sizeof("label=") - 1);
- if (!validate_and_escape_label (&label, 15))
- {
- g_string_free (s, TRUE);
- goto out;
- }
- g_string_append_printf (s, " -L \"%s\"", label);
- g_free (label);
- label = NULL;
- }
- else
- {
- g_printerr ("option %s not supported\n", options[n]);
- goto out;
- }
- }
- g_string_append_printf (s, " %s", device);
- command_line = g_string_free (s, FALSE);
-
- }
- else if (strcmp (fstype, "empty") == 0)
- {
- command_line = NULL;
- for (n = 0; options[n] != NULL; n++)
- {
- g_printerr ("option %s not supported\n", options[n]);
- goto out;
- }
- }
- else
- {
- g_printerr ("fstype %s not supported\n", fstype);
- goto out;
- }
-
- /* scrub signatures */
- if (!scrub_signatures (device, 0, 0))
- goto out;
-
- if (command_line != NULL)
- {
- error = NULL;
- if (!g_spawn_command_line_sync (command_line, NULL, &standard_error, &exit_status, &error))
- {
- g_printerr ("cannot spawn '%s': %s\n", command_line, error->message);
- ret = 3; /* indicate FilesystemToolsMissing error */
- g_error_free (error);
- goto out;
- }
- if (WEXITSTATUS (exit_status) != 0)
- {
- g_printerr ("helper failed with:\n%s", standard_error);
- goto out;
- }
- }
-
- if (label != NULL)
- {
- g_free (command_line);
-
- if (strcmp (fstype, "vfat") == 0)
- {
- command_line = g_strdup_printf ("mlabel -i %s \"::%s\"", device, label);
- }
- else
- {
- g_printerr ("label change for fstype '%s' requested but not implemented", fstype);
- goto out;
- }
-
- error = NULL;
- if (!g_spawn_command_line_sync (command_line, NULL, &standard_error, &exit_status, &error))
- {
- g_printerr ("cannot spawn '%s': %s\n", command_line, error->message);
- g_error_free (error);
- ret = 3; /* indicate FilesystemToolsMissing error */
- goto out;
- }
- if (WEXITSTATUS (exit_status) != 0)
- {
- g_printerr ("helper failed with:\n%s", standard_error);
- goto out;
- }
-
- g_free (label);
- }
-
- /* If we've created an fs on a partitioned device, then signal the
- * kernel to reread the (now missing) partition table.
- */
- if (is_kernel_partitioned)
- {
- fd = open (device, O_RDONLY);
- if (fd < 0)
- {
- g_printerr ("cannot open %s (for BLKRRPART): %m\n", device);
- goto out;
- }
- if (ioctl (fd, BLKRRPART) != 0)
- {
- close (fd);
- g_printerr ("BLKRRPART ioctl failed for %s: %m\n", device);
- goto out;
- }
- close (fd);
- }
-
- /* take ownership of the device if requested */
- if (take_ownership_uid != 0 || take_ownership_gid != 0)
- {
- char dir[256] = PACKAGE_LOCALSTATE_DIR "/run/udisks/job-mkfs-XXXXXX";
-
- if (mkdtemp (dir) == NULL)
- {
- g_printerr ("cannot create directory %s: %m\n", dir);
- goto out;
- }
-
- if (mount (device, dir, fstype, 0, NULL) != 0)
- {
- g_printerr ("cannot mount %s at %s: %m\n", device, dir);
- ret = 2;
- goto tos_err0;
- }
-
- if (chown (dir, take_ownership_uid, take_ownership_gid) != 0)
- {
- g_printerr ("cannot chown %s to uid=%d and gid=%d: %m\n", dir, take_ownership_uid, take_ownership_gid);
- ret = 2;
- }
-
- if (chmod (dir, 0700) != 0)
- {
- g_printerr ("cannot chmod %s to mode 0700: %m\n", dir);
- ret = 2;
- }
-
- if (umount (dir) != 0)
- {
- g_printerr ("cannot unmount %s: %m\n", dir);
- ret = 2;
- goto tos_err0;
- }
-
- tos_err0:
- if (rmdir (dir) != 0)
- {
- g_printerr ("cannot remove directory %s: %m\n", dir);
- goto out;
- }
- }
-
- if (ret == 2)
- ret = 1;
- else
- ret = 0;
-
- out:
- g_free (standard_error);
- g_free (command_line);
- return ret;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#define _LARGEFILE64_SOURCE
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/wait.h>
-
-#include <glib.h>
-
-#include "job-shared.h"
-#include "partutil.h"
-
-int
-main (int argc,
- char **argv)
-{
- int ret;
- const char *device;
- char *label;
- char *type;
- char *flags_as_string;
- char **flags;
- guint64 offset;
- guint64 size;
- guint64 out_start;
- guint64 out_size;
- char *endp;
-
- ret = 1;
- flags = NULL;
-
- if (argc < 7)
- {
- g_printerr ("wrong usage\n");
- goto out;
- }
- device = argv[1];
- offset = strtoll (argv[2], &endp, 10);
- if (*endp != '\0')
- {
- g_printerr ("malformed offset '%s'\n", argv[2]);
- goto out;
- }
- size = strtoll (argv[3], &endp, 10);
- if (*endp != '\0')
- {
- g_printerr ("malformed size '%s'\n", argv[3]);
- goto out;
- }
- type = argv[4];
- label = argv[5];
- flags_as_string = argv[6];
-
- flags = g_strsplit (flags_as_string, ",", 0);
-
- /* we trust the caller have verified that the given slice doesn't overlap
- * with existing partitions
- */
-
- g_print ("type: '%s'\n", type);
- g_print ("label: '%s'\n", label);
- g_print ("flags_as_string: '%s'\n", flags_as_string);
-
- if (part_change_partition ((char *) device,
- offset,
- offset,
- size,
- &out_start,
- &out_size,
- type,
- strlen (label) > 0 ? label : NULL,
- flags,
- -1,
- -1))
- {
- if (out_start != offset || out_size != size)
- {
- g_printerr ("ugh, offset or size changed\n");
- g_printerr ("offset: %" G_GINT64_FORMAT "\n", offset);
- g_printerr ("size: %" G_GINT64_FORMAT "\n", size);
- g_printerr ("new_offset: %" G_GINT64_FORMAT "\n", out_start);
- g_printerr ("new_size: %" G_GINT64_FORMAT "\n", out_size);
- }
- else
- {
- /* success */
- ret = 0;
- }
- }
-
- /* no need to reread partition table as sizes didn't change */
-
- out:
- g_strfreev (flags);
- return ret;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#define _LARGEFILE64_SOURCE
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <linux/fs.h>
-
-#include <glib.h>
-
-#ifndef __JOB_SHARED_H__
-#define __JOB_SHARED_H__
-
-/* TODO: maybe move to private static library if there's a lot of shared stuff */
-
-static inline gboolean
-_do_write (int fd,
- void *buf,
- int num)
-{
- gboolean ret;
- ret = FALSE;
- again:
- if (write (fd, buf, num) != (int) num)
- {
- if (errno == EAGAIN)
- {
- goto again;
- }
- else
- {
- g_printerr ("%d: error writing %d bytes: %m\n", getpid (), num);
- goto out;
- }
- }
- ret = TRUE;
- out:
- return ret;
-}
-
-#if 0
-#define ERASE_SIZE (128*1024)
-static inline gboolean
-_scrub_signatures (int fd, guint64 offset, guint64 size)
-{
- gboolean ret;
- guint64 wipe_size;
- char buf[ERASE_SIZE];
-
- ret = FALSE;
-
- /* wipe first and last 128KB. Note that btrfs keeps signatures at 0x10000 == 64KB. */
- wipe_size = 128 * 1024;
- g_assert (sizeof (buf) >= wipe_size);
-
- if (wipe_size > size)
- {
- wipe_size = size;
- }
-
- if (lseek64 (fd, offset, SEEK_SET) == (off64_t) -1)
- {
- g_printerr ("cannot seek to %" G_GINT64_FORMAT ": %m", offset);
- goto out;
- }
-
- if (!_do_write (fd, buf, wipe_size))
- goto out;
-
- if (lseek64 (fd, offset + size - wipe_size, SEEK_SET) == (off64_t) -1)
- {
- g_printerr ("cannot seek to %" G_GINT64_FORMAT ": %m", offset + size - wipe_size);
- goto out;
- }
-
- if (!_do_write (fd, buf, wipe_size))
- goto out;
-
- ret = TRUE;
-
- out:
- return ret;
-}
-#endif
-
-/**
- * task_zero_device:
- * @device: device to zero
- * @offset: the offset to start zeroing the device
- * @size: if zero is passed, the whole device is zeroed; otherwise size of slice to zero
- *
- * Zeroes (parts of) a device and scrubs all areas containing
- * signatures.
- **/
-static inline gboolean
-scrub_signatures (const char *device,
- guint64 offset,
- guint64 size)
-{
- int fd;
- gboolean ret;
- char buf[128 * 1024];
- guint64 wipe_size;
-
- fd = 0;
- ret = FALSE;
-
- fd = open (device, O_WRONLY);
- if (fd < 0)
- {
- g_printerr ("cannot open %s: %m\n", device);
- goto out;
- }
-
- if (size == 0)
- {
- if (ioctl (fd, BLKGETSIZE64, &size) != 0)
- {
- g_printerr ("cannot determine size of %s: %m\n", device);
- goto out;
- }
- }
-
- memset (buf, '\0', sizeof(buf));
-
- /* wipe first and last 128KB. Note that btrfs keeps signatures at 0x10000 == 64KB. */
- wipe_size = 128 * 1024;
- memset (buf, '\0', sizeof(buf));
-
- if (wipe_size > size)
- {
- wipe_size = size;
- }
-
- if (lseek64 (fd, offset, SEEK_SET) == (off64_t) - 1)
- {
- g_printerr ("cannot seek to %" G_GINT64_FORMAT " on %s: %m", offset, device);
- goto out;
- }
-
- if (!_do_write (fd, buf, wipe_size))
- goto out;
-
- if (lseek64 (fd, offset + size - wipe_size, SEEK_SET) == (off64_t) - 1)
- {
- g_printerr ("cannot seek to %" G_GINT64_FORMAT " on %s: %m", offset + size - wipe_size, device);
- goto out;
- }
-
- if (!_do_write (fd, buf, wipe_size))
- goto out;
-
- ret = TRUE;
-
- out:
- if (fd >= 0)
- {
- if (fsync (fd) != 0)
- {
- g_printerr ("Error calling fsync(2) on %s: %m\n", device);
- ret = FALSE;
- }
- close (fd);
- }
- return ret;
-}
-
-static inline gboolean
-validate_and_escape_label (char **label,
- int max_len)
-{
- int n;
- gboolean ret;
- GString *s;
-
- ret = FALSE;
-
- if ((int) strlen (*label) > max_len)
- {
- g_printerr ("given file system label exceeds %d characters\n", max_len);
- goto out;
- }
-
- /* escape '"' */
- s = g_string_new (*label);
- for (n = 0; n < (int) s->len; n++)
- {
- if (s->str[n] == '"')
- {
- g_string_insert_c (s, n, '\\');
- n++;
- }
- }
- g_free (*label);
- *label = g_string_free (s, FALSE);
-
- ret = TRUE;
- out:
- return ret;
-}
-
-static inline gboolean
-reread_partition_table (const gchar *device_file)
-{
- gint fd;
- gboolean ret;
- guint num_retries;
-
- ret = FALSE;
- num_retries = 0;
-
- fd = open (device_file, O_RDONLY);
- if (fd < 0)
- {
- g_printerr ("cannot open %s (for BLKRRPART): %m\n", device_file);
- goto out;
- }
- try_again:
- if (ioctl (fd, BLKRRPART) != 0)
- {
- if (errno == EBUSY && num_retries < 20)
- {
- usleep (250 * 1000);
- num_retries++;
- goto try_again;
- }
- close (fd);
- g_printerr ("BLKRRPART ioctl failed for %s: %m\n", device_file);
- goto out;
- }
- close (fd);
-
- ret = TRUE;
-
- out:
- return ret;
-}
-
-#endif /* __JOB_SHARED_H__ */
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/***************************************************************************
- *
- * part.c : library for reading and writing partition tables - uses
- * libparted for the heavy lifting
- *
- * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- **************************************************************************/
-
-#define _LARGEFILE64_SOURCE
-
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <ctype.h>
-#include <linux/fs.h>
-
-#include <linux/hdreg.h>
-
-#define BLKGETSIZE64 _IOR(0x12,114,size_t)
-
-#include <glib/gstdio.h>
-#include "partutil.h"
-
-static void
-DEBUG (const gchar *format,
- ...)
-{
-#if 1
- va_list args;
- va_start (args, format);
- g_vfprintf (stderr, format, args);
- va_end (args);
- g_fprintf (stderr, "\n");
- fflush ( stderr);
-#endif
-}
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#define USE_PARTED
-#ifdef USE_PARTED
-#include <parted/parted.h>
-#endif
-
-const char *
-part_get_scheme_name (PartitionScheme scheme)
-{
- const char *s;
-
- switch (scheme)
- {
- case PART_TYPE_GPT:
- s = "gpt";
- break;
- case PART_TYPE_MSDOS:
- s = "mbr";
- break;
- case PART_TYPE_MSDOS_EXTENDED:
- s = "embr";
- break;
- case PART_TYPE_APPLE:
- s = "apm";
- break;
- default:
- s = NULL;
- break;
- }
-
- return s;
-}
-
-struct PartitionEntry_s;
-typedef struct PartitionEntry_s PartitionEntry;
-
-struct PartitionEntry_s
-{
- gboolean is_part_table;
-
- /* NULL iff is_part_table==FALSE */
- PartitionTable *part_table;
-
- /* these are always set */
- guint8 *data;
- int length;
-
- /* offset _on disk_ where the entry starts */
- guint64 offset;
-};
-
-struct PartitionTable_s
-{
- /* partitioning scheme used */
- PartitionScheme scheme;
-
- /* offset of table on disk */
- guint64 offset;
- guint64 size;
-
- /* block size */
- guint64 block_size;
-
- /* entries in partition table */
- GSList *entries;
-};
-
-void
-part_table_find (PartitionTable *p,
- guint64 offset,
- PartitionTable **out_part_table,
- int *out_entry)
-{
- int n;
- int num_entries;
-
- *out_part_table = p;
- *out_entry = -1;
-
- num_entries = part_table_get_num_entries (p);
- for (n = 0; n < num_entries; n++)
- {
- guint64 pe_offset;
- guint64 pe_size;
-
- pe_offset = part_table_entry_get_offset (p, n);
- pe_size = part_table_entry_get_size (p, n);
-
- if ((offset >= pe_offset) && (offset < pe_offset + pe_size))
- {
- PartitionTable *part_table_nested;
-
- part_table_nested = part_table_entry_get_nested (p, n);
- /* return the extended partition only if the offset points to it - otherwise
- * look for a logical partition
- */
- if (part_table_nested != NULL && offset > pe_offset)
- {
- part_table_find (part_table_nested, offset, out_part_table, out_entry);
- }
- else
- {
- *out_entry = n;
- }
-
- /* and we're done... */
- break;
- }
- }
-}
-
-static guint16
-get_le16 (const void *buf)
-{
- return GUINT16_FROM_LE (*((guint16 *) buf));
-}
-
-static guint32
-get_le32 (const void *buf)
-{
- return GUINT32_FROM_LE (*((guint32 *) buf));
-}
-
-static guint64
-get_le64 (const void *buf)
-{
- return GUINT64_FROM_LE (*((guint64 *) buf));
-}
-
-static guint32
-get_be32 (const void *buf)
-{
- return GUINT32_FROM_BE (*((guint32 *) buf));
-}
-
-/* see http://en.wikipedia.org/wiki/Globally_Unique_Identifier - excerpt
- *
- * Guids are most commonly written in text as a sequence of hexadecimal digits as such:
- *
- * 3F2504E0-4F89-11D3-9A0C-0305E82C3301
- *
- * This text notation follows from the data structure defined above. The sequence is
- *
- * 1. Data1 (8 characters)
- * 2. Hyphen
- * 3. Data2 (4 characters)
- * 4. Hyphen
- * 5. Data3 (4 characters)
- * 6. Hyphen
- * 7. Initial two items from Data4 (4 characters)
- * 8. Hyphen
- * 9. Remaining six items from Data4 (12 characters)
- *
- * Often braces are added to enclose the above format, as such:
- *
- * {3F2504E0-4F89-11D3-9A0C-0305E82C3301}
- *
- * When printing fewer characters is desired guids are sometimes encoded
- * into a base64 string of 22 to 24 characters (depending on
- * padding). For instance:
- *
- * 7QDBkvCA1+B9K/U0vrQx1A
- * 7QDBkvCA1+B9K/U0vrQx1A==
- */
-
-typedef struct efi_guid_s
-{
- guint32 data1;
- guint16 data2;
- guint16 data3;
- guint8 data4[8];
-}__attribute__ ((packed)) efi_guid;
-
-static char *
-get_le_guid (const void *buf)
-{
- const efi_guid *guid = (const efi_guid *) buf;
-
- return g_strdup_printf ("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
- get_le32 (&(guid->data1)),
- get_le16 (&(guid->data2)),
- get_le16 (&(guid->data3)),
- guid->data4[0],
- guid->data4[1],
- guid->data4[2],
- guid->data4[3],
- guid->data4[4],
- guid->data4[5],
- guid->data4[6],
- guid->data4[7]);
-}
-
-#ifdef USE_PARTED
-static gboolean
-set_le_guid (guint8 *buf,
- const char *source)
-{
- efi_guid *guid = (efi_guid *) buf;
- guint32 __attribute__((__unused__)) data1;
- guint16 __attribute__((__unused__)) data2;
- guint16 __attribute__((__unused__)) data3;
- guint8 __attribute__((__unused__)) data4[8];
- gboolean ret;
- int n;
-
- ret = FALSE;
-
- n = sscanf (source,
- "%x-%hx-%hx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
- &guid->data1,
- &guid->data2,
- &guid->data3,
- &(guid->data4[0]),
- &(guid->data4[1]),
- &(guid->data4[2]),
- &(guid->data4[3]),
- &(guid->data4[4]),
- &(guid->data4[5]),
- &(guid->data4[6]),
- &(guid->data4[7]));
-
- if (n != 11)
- {
- DEBUG ("guid '%s' is not valid", source);
- goto out;
- }
-
-#if 0
- DEBUG ("source = %s", source);
- DEBUG ("data1 = %08x", guid->data1);
- DEBUG ("data2 = %04x", guid->data2);
- DEBUG ("data3 = %04x", guid->data3);
- DEBUG ("data4[0] = %02x", guid->data4[0]);
- DEBUG ("data4[1] = %02x", guid->data4[1]);
- DEBUG ("data4[2] = %02x", guid->data4[2]);
- DEBUG ("data4[3] = %02x", guid->data4[3]);
- DEBUG ("data4[4] = %02x", guid->data4[4]);
- DEBUG ("data4[5] = %02x", guid->data4[5]);
- DEBUG ("data4[6] = %02x", guid->data4[6]);
- DEBUG ("data4[7] = %02x", guid->data4[7]);
-#endif
-
- guid->data1 = GUINT32_TO_LE (guid->data1);
- guid->data2 = GUINT16_TO_LE (guid->data2);
- guid->data3 = GUINT16_TO_LE (guid->data3);
-
- ret = TRUE;
-
-out:
- return ret;
-}
-#endif
-
-static PartitionEntry *
-part_entry_new (PartitionTable *e_part_table,
- const guint8 *data,
- int length,
- guint64 offset)
-{
- PartitionEntry *pe;
-
- pe = g_new0 (PartitionEntry, 1);
- pe->is_part_table = (e_part_table != NULL);
- pe->part_table = e_part_table;
- pe->offset = offset;
- pe->length = length;
- pe->data = g_new0 (guint8, length);
- memcpy (pe->data, data, length);
-
- return pe;
-}
-
-static void
-part_entry_free (PartitionEntry *pe)
-{
- if (pe->part_table != NULL)
- {
- part_table_free (pe->part_table);
- }
- g_free (pe->data);
- g_free (pe);
-}
-
-static PartitionTable *
-part_table_new_empty (PartitionScheme scheme,
- int block_size)
-{
- PartitionTable *p;
-
- p = g_new0 (PartitionTable, 1);
- p->scheme = scheme;
- p->offset = 0;
- p->entries = NULL;
- p->block_size = block_size;
-
- return p;
-}
-
-void
-part_table_free (PartitionTable *p)
-{
- GSList *i;
-
- if (p == NULL)
- return;
-
- for (i = p->entries; i != NULL; i = i->next)
- {
- PartitionEntry *pe = i->data;
- part_entry_free (pe);
- }
- g_slist_free (p->entries);
- g_free (p);
-}
-
-#if 0
-static PartitionTable *
-part_table_parse_bsd (int fd, guint64 offset, guint64 size, int block_size)
-{
- PartitionTable *p;
-
- p = NULL;
-
- /* TODO */
-
- return p;
-}
-#endif
-
-#define MSDOS_MAGIC "\x55\xaa"
-#define MSDOS_PARTTABLE_OFFSET 0x1be
-#define MSDOS_SIG_OFF 0x1fe
-
-#if 0
-static void
-hexdump (const guint8 *mem, int size)
-{
- int i;
- int j;
- int n;
- const guint8 *buf = (const guint8 *) mem;
-
- n = 0;
- printf ("Dumping %d=0x%x bytes\n", size, size);
- while (n < size)
- {
-
- fprintf (stderr, "0x%04x: ", n);
-
- j = n;
- for (i = 0; i < 16; i++)
- {
- if (j >= size)
- break;
- fprintf (stderr, "%02x ", buf[j]);
- j++;
- }
-
- for (; i < 16; i++)
- {
- fprintf (stderr, " ");
- }
-
- fprintf (stderr, " ");
-
- j = n;
- for (i = 0; i < 16; i++)
- {
- if (j >= size)
- break;
- fprintf (stderr, "%c", isprint(buf[j]) ? buf[j] : '.');
- j++;
- }
-
- fprintf (stderr, "\n");
-
- n += 16;
- }
-}
-#endif
-
-static PartitionTable *
-part_table_parse_msdos_extended (int fd,
- guint64 offset,
- guint64 size,
- int block_size)
-{
- int n;
- PartitionTable *p;
- guint64 next;
-
- DEBUG ("Entering MS-DOS extended parser (offset=%lld, size=%lld)", offset, size);
-
- p = NULL;
-
- next = offset;
-
- while (next != 0)
- {
- guint64 readfrom;
- const guint8 embr[512];
-
- readfrom = next;
- next = 0;
-
- DEBUG ("readfrom = %lld", readfrom);
-
- if ((guint64) lseek64 (fd, readfrom, SEEK_SET) != readfrom)
- {
- DEBUG ("lseek failed (%s)", strerror (errno));
- goto out;
- }
- if (read (fd, &embr, sizeof(embr)) != sizeof(embr))
- {
- DEBUG ("read failed (%s)", strerror (errno));
- goto out;
- }
-
- //hexdump (embr, 512);
-
- if (memcmp (&embr[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0)
- {
- DEBUG ("No MSDOS_MAGIC found");
- goto out;
- }
-
- DEBUG ("MSDOS_MAGIC found");
-
- if (p == NULL)
- {
- p = part_table_new_empty (PART_TYPE_MSDOS_EXTENDED, block_size);
- p->offset = offset;
- p->size = size;
- }
-
- for (n = 0; n < 2; n++)
- {
- PartitionEntry *pe;
- guint64 pstart;
- guint64 psize;
-
- pstart = block_size * ((guint64) get_le32 (&(embr[MSDOS_PARTTABLE_OFFSET + n * 16 + 8])));
- psize = block_size * ((guint64) get_le32 (&(embr[MSDOS_PARTTABLE_OFFSET + n * 16 + 12])));
-
- if (psize == 0)
- continue;
-
- pe = NULL;
-
- if (n == 0)
- {
- //DEBUG ("part %d (offset %lld, size %lld, type 0x%02x)",
- // n, readfrom + pstart, psize, ptype));
-
- //DEBUG ("pstart = %lld", pstart));
-
- //hexdump (&(embr[MSDOS_PARTTABLE_OFFSET + n * 16]), 16);
-
- pe = part_entry_new (NULL, &(embr[MSDOS_PARTTABLE_OFFSET + n * 16]), 16, readfrom
- + MSDOS_PARTTABLE_OFFSET + n * 16);
- }
- else
- {
- if (pstart != 0)
- {
- //DEBUG ("found chain at offset %lld", offset + pstart);
- next = offset + pstart;
- }
- }
-
- //DEBUG ("pe = %p", pe));
-
- if (pe != NULL)
- {
- p->entries = g_slist_append (p->entries, pe);
- }
- }
-
- }
-
- out:
- DEBUG ("Exiting MS-DOS extended parser");
- return p;
-}
-
-static PartitionTable *
-part_table_parse_msdos (int fd,
- guint64 offset,
- guint64 size,
- int block_size,
- gboolean *found_gpt)
-{
- int n;
- const guint8 mbr[512] __attribute__ ((aligned));
- PartitionTable *p;
-
- DEBUG ("Entering MS-DOS parser (offset=%lld, size=%lld)", offset, size);
-
- *found_gpt = FALSE;
-
- p = NULL;
-
- if (lseek64 (fd, offset, SEEK_SET) < 0)
- {
- DEBUG ("lseek failed (%s)", strerror (errno));
- goto out;
- }
- if (read (fd, &mbr, sizeof(mbr)) != sizeof(mbr))
- {
- DEBUG ("read failed (%s)", strerror (errno));
- goto out;
- }
-
- //hexdump (mbr, 512);
-
- if (memcmp (&mbr[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0)
- {
- DEBUG ("No MSDOS_MAGIC found");
- goto out;
- }
-
- DEBUG ("MSDOS_MAGIC found");
-
- /* sanity checks */
- for (n = 0; n < 4; n++)
- {
- if (mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 0] != 0 && mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 0] != 0x80)
- {
- DEBUG ("partitioning flag for part %d is not 0x00 or 0x80", n);
- goto out;
- }
- /* protective MBR for GPT => GPT, not MS-DOS */
- if (mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 4] == 0xee)
- {
- DEBUG ("found partition type 0xee => protective MBR for GPT");
- *found_gpt = TRUE;
- goto out;
- }
- }
-
- p = part_table_new_empty (PART_TYPE_MSDOS, block_size);
- p->offset = offset;
- p->size = size;
-
- /* we _always_ want to create four partitions */
- for (n = 0; n < 4; n++)
- {
- PartitionEntry *pe;
- guint64 pstart;
- guint64 psize;
- guint8 ptype;
- PartitionTable *e_part_table;
-
- pstart = block_size * ((guint64) get_le32 (&(mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 8])));
- psize = block_size * ((guint64) get_le32 (&(mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 12])));
- ptype = mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 4];
-
- DEBUG ("looking at part %d (offset %lld, size %lld, type 0x%02x)", n, pstart, psize, ptype);
-
- pe = NULL;
- e_part_table = NULL;
-
- /* look for embedded partition tables */
- switch (ptype)
- {
-
- /* extended partitions */
- case 0x05: /* MS-DOS */
- case 0x0f: /* Win95 */
- case 0x85: /* Linux */
- e_part_table = part_table_parse_msdos_extended (fd, pstart, psize, block_size);
- if (e_part_table != NULL)
- {
- pe = part_entry_new (e_part_table, &(mbr[MSDOS_PARTTABLE_OFFSET + n * 16]), 16, offset
- + MSDOS_PARTTABLE_OFFSET + n * 16);
- }
- break;
-
- case 0xa5: /* FreeBSD */
- case 0xa6: /* OpenBSD */
- case 0xa9: /* NetBSD */
- //e_part_table = part_table_parse_bsd (fd, pstart, psize, block_size);
- //break;
-
- default:
- DEBUG ("new part entry");
- pe = part_entry_new (NULL, &(mbr[MSDOS_PARTTABLE_OFFSET + n * 16]), 16, offset + MSDOS_PARTTABLE_OFFSET + n
- * 16);
- break;
- }
-
- //DEBUG ("pe = %p", pe));
-
- if (pe != NULL)
- {
- p->entries = g_slist_append (p->entries, pe);
- }
- }
-
- out:
- DEBUG ("Exiting MS-DOS parser");
- return p;
-}
-
-#define GPT_MAGIC "EFI PART"
-
-#define GPT_PART_TYPE_GUID_EMPTY "00000000-0000-0000-0000-000000000000"
-
-static PartitionTable *
-part_table_parse_gpt (int fd,
- guint64 offset,
- guint64 size,
- int block_size)
-{
- int n;
- PartitionTable *p;
- guint8 buf[16];
- guint64 partition_entry_lba;
- int num_entries;
- int size_of_entry;
-
- DEBUG ("Entering EFI GPT parser");
-
- /* by way of getting here, we've already checked for a protective MBR */
-
- p = NULL;
-
- /* Check GPT signature */
- if (lseek64 (fd, offset + 512 + 0, SEEK_SET) < 0)
- {
- DEBUG ("lseek failed (%s)", strerror (errno));
- goto out;
- }
- if (read (fd, buf, 8) != 8)
- {
- DEBUG ("read failed (%s)", strerror (errno));
- goto out;
- }
- if (memcmp (buf, GPT_MAGIC, 8) != 0)
- {
- DEBUG ("No GPT_MAGIC found");
- goto out;
- }
-
- DEBUG ("GPT magic found");
-
- /* Disk UUID */
- if (lseek64 (fd, offset + 512 + 56, SEEK_SET) < 0)
- {
- DEBUG ("lseek failed (%s)", strerror (errno));
- goto out;
- }
- if (read (fd, buf, 16) != 16)
- {
- DEBUG ("read failed (%s)", strerror (errno));
- goto out;
- }
- //hexdump ((guint8*) buf, 16);
-
- if (lseek64 (fd, offset + 512 + 72, SEEK_SET) < 0)
- {
- DEBUG ("lseek failed (%s)", strerror (errno));
- goto out;
- }
- if (read (fd, buf, 8) != 8)
- {
- DEBUG ("read failed (%s)", strerror (errno));
- goto out;
- }
- partition_entry_lba = get_le64 (buf);
-
- if (lseek64 (fd, offset + 512 + 80, SEEK_SET) < 0)
- {
- DEBUG ("lseek failed (%s)", strerror (errno));
- goto out;
- }
- if (read (fd, buf, 4) != 4)
- {
- DEBUG ("read failed (%s)", strerror (errno));
- goto out;
- }
- num_entries = get_le32 (buf);
-
- if (lseek64 (fd, offset + 512 + 84, SEEK_SET) < 0)
- {
- DEBUG ("lseek failed (%s)", strerror (errno));
- goto out;
- }
- if (read (fd, buf, 4) != 4)
- {
- DEBUG ("read failed (%s)", strerror (errno));
- goto out;
- }
- size_of_entry = get_le32 (buf);
-
- p = part_table_new_empty (PART_TYPE_GPT, block_size);
- p->offset = offset;
- p->size = size;
-
- DEBUG ("partition_entry_lba=%lld", partition_entry_lba);
- DEBUG ("num_entries=%d", num_entries);
- DEBUG ("size_of_entry=%d", size_of_entry);
-
- for (n = 0; n < num_entries; n++)
- {
- PartitionEntry *pe;
- struct
- {
- guint8 partition_type_guid[16];
- guint8 partition_guid[16];
- guint8 starting_lba[8];
- guint8 ending_lba[8];
- guint8 attributes[8];
- guint8 partition_name[72];
- } gpt_part_entry;
- char *partition_type_guid;
-
- if (lseek64 (fd, offset + partition_entry_lba * 512 + n * size_of_entry, SEEK_SET) < 0)
- {
- DEBUG ("lseek failed (%s)", strerror (errno));
- goto out;
- }
- if (read (fd, &gpt_part_entry, 128) != 128)
- {
- DEBUG ("read failed (%s)", strerror (errno));
- goto out;
- }
-
- partition_type_guid = get_le_guid (gpt_part_entry.partition_type_guid);
-
- if (strcmp (partition_type_guid, GPT_PART_TYPE_GUID_EMPTY) == 0)
- continue;
-
- pe
- = part_entry_new (NULL, (guint8*) &gpt_part_entry, 128, offset + partition_entry_lba * 512 + n
- * size_of_entry);
- p->entries = g_slist_append (p->entries, pe);
-
- g_free (partition_type_guid);
-
- //hexdump ((guint8 *) &gpt_part_entry, 128);
-
- }
-
- out:
- DEBUG ("Leaving EFI GPT parser");
- return p;
-}
-
-#define MAC_MAGIC "ER"
-#define MAC_PART_MAGIC "PM"
-
-static PartitionTable *
-part_table_parse_apple (int fd,
- guint64 offset,
- guint64 size,
- int device_block_size)
-{
- int n;
- PartitionTable *p;
- struct
- {
- guint16 signature;
- guint16 block_size;
- guint32 block_count;
- /* more stuff */
- }__attribute__ ((packed)) mac_header;
- struct
- {
- guint16 signature;
- guint16 res1;
- guint32 map_count;
- guint32 start_block;
- guint32 block_count;
- char name[32];
- char type[32];
- guint32 data_start;
- guint32 data_count;
- guint32 status;
- guint32 boot_start;
- guint32 boot_size;
- guint32 boot_load;
- guint32 boot_load2;
- guint32 boot_entry;
- guint32 boot_entry2;
- guint32 boot_cksum;
- char processor[16]; /* identifies ISA of boot */
- /* more stuff */
- }__attribute__ ((packed)) mac_part;
- int block_size;
- int block_count;
- int map_count;
-
- DEBUG ("Entering Apple parser");
-
- p = NULL;
-
- /* Check Mac start of disk signature */
- if (lseek64 (fd, offset + 0, SEEK_SET) < 0)
- {
- DEBUG ("lseek failed (%s)", strerror (errno));
- goto out;
- }
- if (read (fd, &mac_header, sizeof(mac_header)) != sizeof(mac_header))
- {
- DEBUG ("read failed (%s)", strerror (errno));
- goto out;
- }
- if (memcmp (&(mac_header.signature), MAC_MAGIC, 2) != 0)
- {
- DEBUG ("No MAC_MAGIC found");
- goto out;
- }
-
- block_size = GUINT16_FROM_BE (mac_header.block_size);
- block_count = GUINT32_FROM_BE (mac_header.block_count); /* num blocks on whole disk */
-
- DEBUG ("Mac MAGIC found, block_size=%d", block_size);
-
- p = part_table_new_empty (PART_TYPE_APPLE, block_size);
- p->offset = offset;
- p->size = size;
-
- /* get number of entries from first entry */
- if (lseek64 (fd, offset + block_size, SEEK_SET) < 0)
- {
- DEBUG ("lseek failed (%s)", strerror (errno));
- goto out;
- }
- if (read (fd, &mac_part, sizeof(mac_part)) != sizeof(mac_part))
- {
- DEBUG ("read failed (%s)", strerror (errno));
- goto out;
- }
- map_count = GUINT32_FROM_BE (mac_part.map_count); /* num blocks in part map */
-
- DEBUG ("map_count = %d", map_count);
-
- for (n = 0; n < map_count; n++)
- {
- PartitionEntry *pe;
-
- if (memcmp (&(mac_part.signature), MAC_PART_MAGIC, 2) != 0)
- {
- DEBUG ("No MAC_PART_MAGIC found");
- break;
- }
-
- if (lseek64 (fd, offset + (n + 1) * block_size, SEEK_SET) < 0)
- {
- DEBUG ("lseek failed (%s)", strerror (errno));
- goto out;
- }
- if (read (fd, &mac_part, sizeof(mac_part)) != sizeof(mac_part))
- {
- DEBUG ("read failed (%s)", strerror (errno));
- goto out;
- }
-
- pe = part_entry_new (NULL, (guint8*) &mac_part, sizeof(mac_part), offset + (n + 1) * block_size);
- p->entries = g_slist_append (p->entries, pe);
-
- }
-
- out:
- DEBUG ("Leaving Apple parser");
- return p;
-}
-
-static PartitionTable *
-part_table_load_from_disk_from_file (char *device_file)
-{
- int fd;
- PartitionTable *ret;
-
- ret = NULL;
-
- fd = open (device_file, O_RDONLY);
- if (fd < 0)
- {
- DEBUG ("Cannot open '%s': %m", device_file);
- goto out;
- }
-
- ret = part_table_load_from_disk (fd);
- close (fd);
- out:
- return ret;
-}
-
-PartitionTable *
-part_table_load_from_disk (int fd)
-{
- int block_size;
- guint64 size;
- PartitionTable *p;
- gboolean found_gpt;
-
- p = NULL;
-
- if (ioctl (fd, BLKGETSIZE64, &size) != 0)
- {
- DEBUG ("Cannot determine size of device");
- goto out;
- }
-
- if (ioctl (fd, BLKSSZGET, &block_size) != 0)
- {
- DEBUG ("Cannot determine block size");
- goto out;
- }
-
-#ifdef POSIX_FADV_RANDOM
- /* No read-ahead, please */
- posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM);
-#endif
-
- p = part_table_parse_msdos (fd, 0, size, block_size, &found_gpt);
- if (p != NULL)
- {
- DEBUG ("MSDOS partition table detected");
- goto out;
- }
-
- if (found_gpt)
- {
- p = part_table_parse_gpt (fd, 0, size, block_size);
- if (p != NULL)
- {
- DEBUG ("EFI GPT partition table detected");
- goto out;
- }
- }
-
- p = part_table_parse_apple (fd, 0, size, block_size);
- if (p != NULL)
- {
- DEBUG ("Apple partition table detected");
- goto out;
- }
-
- DEBUG ("No known partition table found");
-
- out:
- return p;
-}
-
-PartitionScheme
-part_table_get_scheme (PartitionTable *p)
-{
- return p->scheme;
-}
-
-int
-part_table_get_num_entries (PartitionTable *p)
-{
- return g_slist_length (p->entries);
-}
-
-guint64
-part_table_get_offset (PartitionTable *p)
-{
- return p->offset;
-}
-
-guint64
-part_table_get_size (PartitionTable *p)
-{
- return p->size;
-}
-
-PartitionTable *
-part_table_entry_get_nested (PartitionTable *p,
- int entry)
-{
- PartitionEntry *pe;
-
- if (p == NULL)
- return NULL;
-
- if ((pe = g_slist_nth_data (p->entries, entry)) == NULL)
- return NULL;
-
- if (pe->is_part_table)
- return pe->part_table;
- else
- return NULL;
-}
-
-/**************************************************************************/
-
-gboolean
-part_table_entry_is_in_use (PartitionTable *p,
- int entry)
-{
- gboolean ret;
- PartitionEntry *pe;
-
- ret = FALSE;
-
- if (p == NULL)
- goto out;
-
- if ((pe = g_slist_nth_data (p->entries, entry)) == NULL)
- goto out;
-
- switch (p->scheme)
- {
- case PART_TYPE_GPT:
- ret = TRUE;
- break;
- case PART_TYPE_MSDOS:
- case PART_TYPE_MSDOS_EXTENDED:
- if (part_table_entry_get_offset (p, entry) == 0)
- ret = FALSE;
- else
- ret = TRUE;
- break;
- case PART_TYPE_APPLE:
- ret = TRUE;
- break;
- default:
- break;
- }
- out:
- return ret;
-}
-
-char *
-part_table_entry_get_type (PartitionTable *p,
- int entry)
-{
- char *s = NULL;
- PartitionEntry *pe;
-
- if (p == NULL)
- goto out;
-
- if ((pe = g_slist_nth_data (p->entries, entry)) == NULL)
- goto out;
-
- switch (p->scheme)
- {
- case PART_TYPE_GPT:
- s = get_le_guid (&(pe->data[0]));
- break;
- case PART_TYPE_MSDOS:
- case PART_TYPE_MSDOS_EXTENDED:
- s = g_strdup_printf ("0x%02x", pe->data[4]);
- break;
- case PART_TYPE_APPLE:
- s = g_strdup ((char *) pe->data + 2 * 2 + 3 * 4 + 32);
- g_strchomp (s);
- break;
- default:
- break;
- }
- out:
- if (s != NULL)
- {
- g_strchomp (s);
- }
- return s;
-}
-
-char *
-part_table_entry_get_uuid (PartitionTable *p,
- int entry)
-{
- char *s = NULL;
- PartitionEntry *pe;
-
- if (p == NULL)
- goto out;
-
- if ((pe = g_slist_nth_data (p->entries, entry)) == NULL)
- goto out;
-
- switch (p->scheme)
- {
- case PART_TYPE_GPT:
- s = get_le_guid (&(pe->data[16]));
- break;
- default:
- break;
- }
- out:
- if (s != NULL)
- {
- g_strchomp (s);
- }
- return s;
-}
-
-char *
-part_table_entry_get_label (PartitionTable *p,
- int entry)
-{
- char *s = NULL;
- PartitionEntry *pe;
-
- if (p == NULL)
- goto out;
-
- if ((pe = g_slist_nth_data (p->entries, entry)) == NULL)
- goto out;
-
- switch (p->scheme)
- {
- case PART_TYPE_GPT:
- s = g_utf16_to_utf8 ((const gunichar2 *) &(pe->data[56]), 36, NULL, NULL, NULL);
- break;
- case PART_TYPE_APPLE:
- s = g_strdup ((char *) pe->data + 2 * 2 + 3 * 4);
- g_strchomp (s);
- break;
- default:
- break;
- }
- out:
- if (s != NULL)
- {
- g_strchomp (s);
- }
- return s;
-}
-
-char **
-part_table_entry_get_flags (PartitionTable *p,
- int entry)
-{
- int n;
- char **ss = NULL;
- guint32 apm_status;
- guint64 gpt_attributes;
- PartitionEntry *pe;
-
- if (p == NULL)
- goto out;
-
- if ((pe = g_slist_nth_data (p->entries, entry)) == NULL)
- goto out;
-
- ss = g_new0 (char*, 6 + 1); /* hard coded to max items we'll return */
- ss[0] = NULL;
- n = 0;
-
- switch (p->scheme)
- {
- case PART_TYPE_GPT:
- gpt_attributes = get_le64 (&(pe->data[48]));
-
- /* From Table 16 of EFI 2.0 spec, bit zero means:
- *
- * "Required for the platform to function. The system
- * cannot function normally if this partition is
- * removed. This partition should be considered as
- * part of the hardware of the system, and if it is
- * removed the system may not boot. It may contain
- * diagnostics, recovery tools, or other code or data
- * that is critical to the functioning of a system
- * independent of any OS."
- *
- */
- if (gpt_attributes & (1 << 0))
- {
- ss[n++] = g_strdup ("required");
- }
-
- /* TODO: handle partition type specific attributes
- *
- * Found on the Internet: "For basic data partitions, the following attribute is
- * defined:0x8000000000000000 prevents the partition from having a drive letter automatically
- * assigned. By default, each partition is assigned a new drive letter. Setting this
- * attribute ensures that when a disk is moved to a new computer, a new drive letter
- * will not be automatically generated. Instead, the user can manually assign drive
- * letters. Note: Other attributes can be added at any time."
- */
- break;
-
- case PART_TYPE_MSDOS:
- case PART_TYPE_MSDOS_EXTENDED:
- if (pe->data[0] == 0x80)
- {
- ss[n++] = g_strdup ("boot");
- }
- break;
-
- case PART_TYPE_APPLE:
- apm_status = get_be32 (&(pe->data[2 * 2 + 3 * 4 + 2 * 32 + 2 * 4]));
- if (apm_status & (1 << 1))
- ss[n++] = g_strdup ("allocated");
- if (apm_status & (1 << 2))
- ss[n++] = g_strdup ("in_use");
- if (apm_status & (1 << 3))
- ss[n++] = g_strdup ("boot");
- if (apm_status & (1 << 4))
- ss[n++] = g_strdup ("allow_read");
- if (apm_status & (1 << 5))
- ss[n++] = g_strdup ("allow_write");
- if (apm_status & (1 << 6))
- ss[n++] = g_strdup ("boot_code_is_pic");
- break;
- default:
- break;
- }
- ss[n] = NULL;
-
- out:
- return ss;
-}
-
-guint64
-part_table_entry_get_offset (PartitionTable *p,
- int entry)
-{
- guint64 val;
- PartitionEntry *pe;
-
- val = G_MAXUINT64;
- if (p == NULL)
- goto out;
-
- if ((pe = g_slist_nth_data (p->entries, entry)) == NULL)
- goto out;
-
- switch (p->scheme)
- {
- case PART_TYPE_GPT:
- val = p->block_size * ((guint64) get_le64 (pe->data + 32));
- break;
-
- case PART_TYPE_MSDOS:
- val = p->block_size * ((guint64) get_le32 (pe->data + 8));
- break;
- case PART_TYPE_MSDOS_EXTENDED:
- /* tricky here.. the offset in the EMBR is from the start of the EMBR and they are
- * scattered around the ext partition... Hence, just use the entry's offset and subtract
- * it's offset from the EMBR..
- */
- val = p->block_size * ((guint64) get_le32 (pe->data + 8)) + pe->offset - MSDOS_PARTTABLE_OFFSET;
- break;
- case PART_TYPE_APPLE:
- val = p->block_size * ((guint64) get_be32 (pe->data + 2 * 2 + 1 * 4));
- break;
- default:
- break;
- }
- out:
- return val;
-}
-
-guint64
-part_table_entry_get_size (PartitionTable *p,
- int entry)
-{
- guint64 val;
- PartitionEntry *pe;
-
- val = G_MAXUINT64;
- if (p == NULL)
- goto out;
-
- if ((pe = g_slist_nth_data (p->entries, entry)) == NULL)
- goto out;
-
- switch (p->scheme)
- {
- case PART_TYPE_GPT:
- val = p->block_size * (((guint64) get_le64 (pe->data + 40)) - ((guint64) get_le64 (pe->data + 32)) + 1);
- break;
- case PART_TYPE_MSDOS:
- case PART_TYPE_MSDOS_EXTENDED:
- val = p->block_size * ((guint64) get_le32 (pe->data + 12));
- break;
- case PART_TYPE_APPLE:
- val = p->block_size * ((guint64) get_be32 (pe->data + 2 * 2 + 2 * 4));
- break;
- default:
- break;
- }
- out:
- return val;
-}
-
-/**************************************************************************/
-
-#ifdef USE_PARTED
-
-/* internal function to both add OR change a partition - if size==0,
- * then we're changing, otherwise we're adding
- */
-
-static gboolean
-part_add_change_partition (char *device_file,
- guint64 start,
- guint64 size,
- guint64 new_start,
- guint64 new_size,
- guint64 *out_start,
- guint64 *out_size,
- guint *out_num,
- char *type,
- char *label,
- char **flags,
- int geometry_hps,
- int geometry_spt,
- gboolean poke_kernel)
-{
- int n;
- gboolean is_change;
- gboolean res;
- PedDevice *device;
- PedDisk *disk;
- PedPartition *part;
- PedConstraint* constraint;
- PedPartitionType ped_type;
- guint64 start_sector;
- guint64 end_sector;
- guint64 new_start_sector;
- guint64 new_end_sector;
- PartitionScheme scheme;
- guint8 mbr_flags = 0;
- guint8 mbr_part_type = 0;
- char *endp;
- guint64 gpt_attributes = 0;
- guint32 apm_status = 0;
-
- res = FALSE;
-
- is_change = FALSE;
- if (size == 0)
- {
- is_change = TRUE;
- }
-
- if (is_change)
- {
- DEBUG ("In part_change_partition: device_file=%s, start=%lld, new_start=%lld, new_size=%lld, type=%s",
- device_file,
- start,
- new_start,
- new_size,
- type);
- }
- else
- {
- DEBUG ("In part_add_partition: device_file=%s, start=%lld, size=%lld, type=%s", device_file, start, size, type);
- }
-
- scheme = -1;
- if (is_change)
- {
- PartitionTable *p;
- PartitionTable *container_p;
- int container_entry;
-
- /* if changing something, make sure the partition to change actually exists */
-
- p = part_table_load_from_disk_from_file (device_file);
- if (p == NULL)
- {
- DEBUG ("Cannot load partition table from %s", device_file);
- goto out;
- }
- part_table_find (p, start + 512, &container_p, &container_entry);
- scheme = part_table_get_scheme (container_p);
- DEBUG ("containing partition table scheme = %d", scheme);
- part_table_free (p);
-
- if (container_entry < 0)
- {
- DEBUG ("Couldn't find partition to change");
- goto out;
- }
- }
- else
- {
- PartitionTable *p;
- PartitionTable *container_p;
- int container_entry;
-
- /* if adding, try to find the scheme of the partition table.. don't error out if we can't find it */
- p = part_table_load_from_disk_from_file (device_file);
- if (p != NULL)
- {
- part_table_find (p, start + 512, &container_p, &container_entry);
- scheme = part_table_get_scheme (container_p);
- DEBUG ("containing partition table scheme = %d", scheme);
- part_table_free (p);
- }
- }
-
- /* now that we know the partitoning scheme, sanity check type and flags */
- switch (scheme)
- {
- case -1:
- /* unknown partition table format; error out if any type, label or flags are given */
- if ((flags != NULL && flags[0] != NULL))
- {
- DEBUG ("unknown partition table format and flags is not empty");
- goto out;
- }
-
- if (type != NULL && strlen (type) > 0)
- {
- DEBUG ("unknown partition table format and type is not empty");
- goto out;
- }
-
- if (label != NULL && strlen (label) > 0)
- {
- DEBUG ("unknown partition table format and label is not empty");
- goto out;
- }
- break;
-
- case PART_TYPE_MSDOS:
- case PART_TYPE_MSDOS_EXTENDED:
- mbr_flags = 0;
- if (flags != NULL)
- {
- for (n = 0; flags[n] != NULL; n++)
- {
- if (strcmp (flags[n], "boot") == 0)
- {
- mbr_flags |= 0x80;
- }
- else
- {
- DEBUG ("unknown flag '%s'", flags[n]);
- goto out;
- }
- }
- }
-
- if (type != NULL)
- {
- mbr_part_type = (guint8) (strtol (type, &endp, 0));
- if (*endp != '\0')
- {
- DEBUG ("invalid type '%s' given", type);
- goto out;
- }
- }
-
- if (label != NULL)
- {
- DEBUG ("labeled partitions not supported on MSDOS or MSDOS_EXTENDED");
- goto out;
- }
-
- break;
-
- case PART_TYPE_GPT:
- gpt_attributes = 0;
- if (flags != NULL)
- {
- for (n = 0; flags[n] != NULL; n++)
- {
- if (strcmp (flags[n], "required") == 0)
- {
- gpt_attributes |= 1;
- }
- else
- {
- DEBUG ("unknown flag '%s'", flags[n]);
- goto out;
- }
- }
- }
- break;
-
- case PART_TYPE_APPLE:
- apm_status = 0;
- if (flags != NULL)
- {
- for (n = 0; flags[n] != NULL; n++)
- {
- if (strcmp (flags[n], "allocated") == 0)
- {
- apm_status |= (1 << 1);
- }
- else if (strcmp (flags[n], "in_use") == 0)
- {
- apm_status |= (1 << 2);
- }
- else if (strcmp (flags[n], "boot") == 0)
- {
- apm_status |= (1 << 3);
- }
- else if (strcmp (flags[n], "allow_read") == 0)
- {
- apm_status |= (1 << 4);
- }
- else if (strcmp (flags[n], "allow_write") == 0)
- {
- apm_status |= (1 << 5);
- }
- else if (strcmp (flags[n], "boot_code_is_pic") == 0)
- {
- apm_status |= (1 << 6);
- }
- else
- {
- DEBUG ("unknown flag '%s'", flags[n]);
- goto out;
- }
- }
- }
- break;
-
- default:
- DEBUG ("partitioning scheme %d not supported", scheme);
- goto out;
- }
-
- switch (scheme)
- {
- case PART_TYPE_MSDOS:
- if (mbr_part_type == 0x05 || mbr_part_type == 0x85 || mbr_part_type == 0x0f)
- {
- ped_type = PED_PARTITION_EXTENDED;
- }
- else
- {
- ped_type = PED_PARTITION_NORMAL;
- }
- break;
-
- case PART_TYPE_MSDOS_EXTENDED:
- ped_type = PED_PARTITION_LOGICAL;
- if (mbr_part_type == 0x05 || mbr_part_type == 0x85 || mbr_part_type == 0x0f)
- {
- DEBUG ("Cannot create an extended partition inside an extended partition");
- goto out;
- }
- break;
-
- default:
- ped_type = PED_PARTITION_NORMAL;
- break;
- }
-
- /* now, create the partition */
-
- start_sector = start / 512;
- end_sector = (start + size) / 512 - 1;
- new_start_sector = new_start / 512;
- new_end_sector = (new_start + new_size) / 512 - 1;
-
- device = ped_device_get (device_file);
- if (device == NULL)
- {
- DEBUG ("ped_device_get() failed");
- goto out;
- }
- DEBUG ("got it");
-
- /* set drive geometry on libparted object if the user requested it */
- if (geometry_hps > 0 && geometry_spt > 0)
- {
- /* not sure this is authorized use of libparted, but, eh, it seems to work */
- device->hw_geom.cylinders = device->bios_geom.cylinders = device->length / geometry_hps / geometry_spt;
- device->hw_geom.heads = device->bios_geom.heads = geometry_hps;
- device->hw_geom.sectors = device->bios_geom.sectors = geometry_spt;
- }
-
- disk = ped_disk_new (device);
- if (disk == NULL)
- {
- DEBUG ("ped_disk_new() failed");
- goto out_ped_device;
- }
- DEBUG ("got disk");
-
- if (!is_change)
- {
- part = ped_partition_new (disk, ped_type, NULL, start_sector, end_sector);
- if (part == NULL)
- {
- DEBUG ("ped_partition_new() failed");
- goto out_ped_disk;
- }
- DEBUG ("new partition");
- }
- else
- {
- part = ped_disk_get_partition_by_sector (disk, start_sector);
- if (part == NULL)
- {
- DEBUG ("ped_partition_get_by_sector() failed");
- goto out_ped_disk;
- }
- DEBUG ("got partition");
- }
-
- /* TODO HACK XXX FIXME UGLY BAD: This is super ugly abuse of
- * libparted - we poke at their internal data structures - but
- * there ain't nothing we can do about it until libparted
- * provides API for this...
- */
- if (scheme == PART_TYPE_GPT)
- {
- struct
- {
- efi_guid type;
- /* more stuff */
- }*gpt_data = (void *) part->disk_specific;
-
- if (type != NULL)
- {
- if (!set_le_guid ((guint8*) &gpt_data->type, type))
- {
- DEBUG ("type '%s' for GPT appear to be malformed", type);
- goto out_ped_partition;
- }
- }
-
- ped_partition_set_flag (part, PED_PARTITION_HIDDEN, (gpt_attributes & 1) != 0);
-
- }
- else if (scheme == PART_TYPE_MSDOS || scheme == PART_TYPE_MSDOS_EXTENDED)
- {
- struct
- {
- unsigned char system;
- /* more stuff */
- }*dos_data = (void *) part->disk_specific;
-
- if (type != NULL)
- {
- dos_data->system = mbr_part_type;
- }
-
- ped_partition_set_flag (part, PED_PARTITION_BOOT, (mbr_flags & 0x80) != 0);
-
- }
- else if (scheme == PART_TYPE_APPLE)
- {
- struct
- {
- char volume_name[33]; /* eg: "Games" */
- char system_name[33]; /* eg: "Apple_Unix_SVR2" */
- char processor_name[17];
- int is_boot;
- int is_driver;
- int has_driver;
- int is_root;
- int is_swap;
- int is_lvm;
- int is_raid;
- PedSector data_region_length;
- PedSector boot_region_length;
- guint32 boot_base_address;
- guint32 boot_entry_address;
- guint32 boot_checksum;
- guint32 status;
- /* more stuff */
- }*mac_data = (void *) part->disk_specific;
-
- if (type != NULL)
- {
- memset (mac_data->system_name, 0, 33);
- strncpy (mac_data->system_name, type, 32);
- }
-
- if (flags != NULL)
- {
- mac_data->status = apm_status;
- }
- }
-
- if (label != NULL)
- {
- ped_partition_set_name (part, label);
- }
-
- if (geometry_hps > 0 && geometry_spt > 0)
- {
- /* respect drive geometry */
- constraint = ped_constraint_any (device);
- }
- else if (geometry_hps == -1 && geometry_spt == -1)
- {
-
- /* undocumented (or is it?) libparted usage again.. it appears that
- * the probed geometry is stored in hw_geom
- */
- device->bios_geom.cylinders = device->hw_geom.cylinders;
- device->bios_geom.heads = device->hw_geom.heads;
- device->bios_geom.sectors = device->hw_geom.sectors;
-
- constraint = ped_constraint_any (device);
- }
- else
- {
- PedGeometry *geo_start;
- PedGeometry *geo_end;
-
- /* ignore drive geometry */
- if (is_change)
- {
- geo_start = ped_geometry_new (device, new_start_sector, 1);
- geo_end = ped_geometry_new (device, new_end_sector, 1);
- }
- else
- {
- geo_start = ped_geometry_new (device, start_sector, 1);
- geo_end = ped_geometry_new (device, end_sector, 1);
- }
-
- constraint = ped_constraint_new (ped_alignment_any, ped_alignment_any, geo_start, geo_end, 1, device->length);
- }
-
- try_change_again:
- if (is_change)
- {
- if (ped_disk_set_partition_geom (disk, part, constraint, new_start_sector, new_end_sector) == 0)
- {
- DEBUG ("ped_disk_set_partition_geom() failed");
- goto out_ped_constraint;
- }
- }
- else
- {
- if (ped_disk_add_partition (disk, part, constraint) == 0)
- {
- DEBUG ("ped_disk_add_partition() failed");
- goto out_ped_constraint;
- }
- }
-
- if (out_start != NULL)
- *out_start = part->geom.start * 512;
- if (out_size != NULL)
- *out_size = part->geom.length * 512;
- if (out_num != NULL)
- *out_num = part->num;
-
- if (is_change)
- {
- /* make sure the resulting size is never smaller than requested
- * (this is because one will resize the FS and *then* change the partition table)
- */
- if (*out_size < new_size)
- {
- DEBUG ("new_size=%lld but resulting size, %lld, smaller than requested", new_size, *out_size);
- new_end_sector++;
- goto try_change_again;
- }
- else
- {
- DEBUG ("changed partition to start=%lld size=%lld", *out_start, *out_size);
- }
- }
- else
- {
- DEBUG ("added partition start=%lld size=%lld", *out_start, *out_size);
- }
-
- /* hmm, if we don't do this libparted crashes.. I assume that
- * ped_disk_add_partition assumes ownership of the
- * PedPartition when adding it... sadly this is not documented
- * anywhere.. sigh..
- */
- part = NULL;
-
- if (poke_kernel)
- {
- if (ped_disk_commit (disk) == 0)
- {
- DEBUG ("ped_disk_commit() failed");
- goto out_ped_disk;
- }
- }
- else
- {
- if (ped_disk_commit_to_dev (disk) == 0)
- {
- DEBUG ("ped_disk_commit_to_dev() failed");
- goto out_ped_constraint;
- }
- }
- DEBUG ("committed to disk");
-
- res = TRUE;
-
- ped_constraint_destroy (constraint);
- ped_disk_destroy (disk);
- ped_device_destroy (device);
- goto out;
-
- out_ped_constraint:
- ped_constraint_destroy (constraint);
-
- out_ped_partition:
- if (part != NULL)
- {
- ped_partition_destroy (part);
- }
-
- out_ped_disk:
- ped_disk_destroy (disk);
-
- out_ped_device:
- ped_device_destroy (device);
-
- out:
- return res;
-}
-
-gboolean
-part_add_partition (char *device_file,
- guint64 start,
- guint64 size,
- guint64 *out_start,
- guint64 *out_size,
- guint *out_num,
- char *type,
- char *label,
- char **flags,
- int geometry_hps,
- int geometry_spt,
- gboolean poke_kernel)
-{
- return part_add_change_partition (device_file,
- start,
- size,
- 0,
- 0,
- out_start,
- out_size,
- out_num,
- type,
- label,
- flags,
- geometry_hps,
- geometry_spt,
- poke_kernel);
-}
-
-gboolean
-part_change_partition (char *device_file,
- guint64 start,
- guint64 new_start,
- guint64 new_size,
- guint64 *out_start,
- guint64 *out_size,
- char *type,
- char *label,
- char **flags,
- int geometry_hps,
- int geometry_spt)
-{
- return part_add_change_partition (device_file,
- start,
- 0,
- new_start,
- new_size,
- out_start,
- out_size,
- NULL,
- type,
- label,
- flags,
- geometry_hps,
- geometry_spt,
- FALSE);
-}
-
-gboolean
-part_del_partition (char *device_file,
- guint64 offset,
- gboolean poke_kernel)
-{
- gboolean ret;
- PedDevice *device;
- PedDisk *disk;
- PedPartition *part;
- PartitionTable *p;
- gboolean is_extended;
- int n;
-
- DEBUG ("In part_del_partition: device_file=%s, offset=%lld", device_file, offset);
- ret = FALSE;
-
- /* sigh.. one would think that if you passed the sector of where the
- * the beginning of the extended partition starts, then _by_sector
- * would return the same as _extended_partition.
- *
- * Sadly it's not so..
- *
- * So, check if the passed offset actually corresponds to a nested
- * partition table...
- */
- is_extended = FALSE;
- p = part_table_load_from_disk_from_file (device_file);
- if (p != NULL)
- {
- for (n = 0; n < part_table_get_num_entries (p); n++)
- {
- PartitionTable *nested;
- nested = part_table_entry_get_nested (p, n);
- if (nested != NULL)
- {
- if (part_table_get_offset (nested) == offset)
- {
- DEBUG ("partition to delete is an extended partition");
- is_extended = TRUE;
- }
- }
- }
- part_table_free (p);
- }
-
- device = ped_device_get (device_file);
- if (device == NULL)
- {
- DEBUG ("ped_device_get() failed");
- goto out;
- }
- DEBUG ("got it");
-
- disk = ped_disk_new (device);
- if (disk == NULL)
- {
- DEBUG ("ped_disk_new() failed");
- goto out_ped_device;
- }
- DEBUG ("got disk");
-
- if (is_extended)
- {
- part = ped_disk_extended_partition (disk);
- }
- else
- {
- part = ped_disk_get_partition_by_sector (disk, offset / 512);
- }
-
- if (part == NULL)
- {
- DEBUG ("ped_disk_get_partition_by_sector() failed");
- goto out_ped_disk;
- }
-
- DEBUG ("got partition - part->type=%d", part->type);
-
- if (part->type & PED_PARTITION_METADATA)
- {
- DEBUG ("refusing to delete a metadata partition");
- goto out_ped_disk;
- }
-
- if (part->type & PED_PARTITION_PROTECTED)
- {
- DEBUG ("refusing to delete a protected partition");
- goto out_ped_disk;
- }
-
- if (part->type & PED_PARTITION_FREESPACE)
- {
- DEBUG ("refusing to delete a protected partition");
- goto out_ped_disk;
- }
-
- if (ped_disk_delete_partition (disk, part) == 0)
- {
- DEBUG ("ped_disk_delete_partition() failed");
- goto out_ped_disk;
- }
-
- if (poke_kernel)
- {
- if (ped_disk_commit (disk) == 0)
- {
- DEBUG ("ped_disk_commit() failed");
- goto out_ped_disk;
- }
- }
- else
- {
- if (ped_disk_commit_to_dev (disk) == 0)
- {
- DEBUG ("ped_disk_commit_to_dev() failed");
- goto out_ped_disk;
- }
- }
- DEBUG ("committed to disk");
-
- ret = TRUE;
-
- ped_disk_destroy (disk);
- ped_device_destroy (device);
- goto out;
-
- out_ped_disk:
- ped_disk_destroy (disk);
-
- out_ped_device:
- ped_device_destroy (device);
-
- out:
- return ret;
-}
-
-gboolean
-part_create_partition_table (char *device_file,
- PartitionScheme scheme)
-{
- PedDevice *device;
- PedDisk *disk;
- PedDiskType *disk_type;
- gboolean ret;
-
- ret = FALSE;
-
- DEBUG ("In part_create_partition_table: device_file=%s, scheme=%d", device_file, scheme);
-
- device = ped_device_get (device_file);
- if (device == NULL)
- {
- DEBUG ("ped_device_get() failed");
- goto out;
- }
- DEBUG ("got it");
-
- switch (scheme)
- {
- case PART_TYPE_MSDOS:
- disk_type = ped_disk_type_get ("msdos");
- break;
- case PART_TYPE_APPLE:
- disk_type = ped_disk_type_get ("mac");
- break;
- case PART_TYPE_GPT:
- disk_type = ped_disk_type_get ("gpt");
- break;
- default:
- disk_type = NULL;
- break;
- }
-
- if (disk_type == NULL)
- {
- DEBUG ("Unknown or unsupported partitioning scheme %d", scheme);
- goto out;
- }
-
- disk = ped_disk_new_fresh (device, disk_type);
- if (disk == NULL)
- {
- DEBUG ("ped_disk_new_fresh() failed");
- goto out_ped_device;
- }
- DEBUG ("got disk");
-
- if (ped_disk_commit_to_dev (disk) == 0)
- {
- DEBUG ("ped_disk_commit_to_dev() failed");
- goto out_ped_disk;
- }
- DEBUG ("committed to disk");
-
- ret = TRUE;
-
- ped_disk_destroy (disk);
- ped_device_destroy (device);
- goto out;
-
- out_ped_disk:
- ped_disk_destroy (disk);
-
- out_ped_device:
- ped_device_destroy (device);
-
- out:
- return ret;
-}
-
-#endif /* USE_PARTED */
-
-/**************************************************************************/
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-/***************************************************************************
- *
- * part.h : library for reading and writing partition tables - uses
- * libparted for the heavy lifting
- *
- * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- **************************************************************************/
-
-#ifndef PARTUTIL_H
-#define PARTUTIL_H
-
-#include <stdio.h>
-#include <glib.h>
-
-/* Partition schemes understood by this library */
-typedef enum
- {
- PART_TYPE_MSDOS = 0,
- PART_TYPE_MSDOS_EXTENDED = 1,
- PART_TYPE_APPLE = 2,
- PART_TYPE_GPT = 3
- } PartitionScheme;
-
-/**
- * part_get_scheme_name:
- * @scheme: the partitioning scheme
- *
- * Get a name for the partitioning scheme. The current mapping is used
- *
- * PART_TYPE_MSDOS -> mbr
- * PART_TYPE_MSDOS_EXTENDED -> embr
- * PART_TYPE_APPLE -> apm
- * PART_TYPE_GPT -> gpt
- *
- * Returns: Name of scheme or NULL for unknown scheme. Caller shall not free this string.
- */
-const char *
-part_get_scheme_name (PartitionScheme scheme);
-
-struct PartitionTable_s;
-typedef struct PartitionTable_s PartitionTable;
-
-/**
- * part_table_load_from_disk:
- * @fd: a file descriptor for the disk
- *
- * Scans a disk and collect all partition entries and nested partition tables.
- *
- * Returns: A partition table object. Use part_table_free() to free this object.
- */
-PartitionTable *
-part_table_load_from_disk (int fd);
-
-/**
- * part_table_free:
- * @part_table: the partition table
- *
- * Frees the partition table returned from part_table_load_from_disk().
- */
-void
-part_table_free (PartitionTable *part_table);
-
-/* partition table inspection */
-
-/**
- * part_table_get_scheme:
- * @part_table: the partition table
- *
- * Get partitioning scheme.
- *
- * Returns: The partitioning scheme.
- */
-PartitionScheme
-part_table_get_scheme (PartitionTable *part_table);
-
-/**
- * part_table_get_num_entries:
- * @part_table: the partition table
- *
- * Get number of entries in partition table.
- *
- * Returns: Number of entries.
- */
-int
-part_table_get_num_entries (PartitionTable *part_table);
-
-/**
- * part_table_get_offset:
- * @part_table: the partition table
- *
- * Get offset from start of disk where partition table starts (as
- * referenced in the partition table entry if it's an embedded
- * partition table, otherwise zero for the full disk)
- *
- * Returns: offset, from start of disk, in bytes
- */
-guint64
-part_table_get_offset (PartitionTable *part_table);
-
-/**
- * part_table_get_size:
- * @part_table: the partition table
- *
- * Get size of partition table (as referenced in the partition table
- * entry if it's an embedded partition table, otherwise the size of
- * the full disk)
- *
- * Returns: size of partition, in bytes
- */
-guint64
-part_table_get_size (PartitionTable *part_table);
-
-/**
- * part_table_find:
- * @part_table: the partition table
- * @offset: the offset to test for
- * @out_part_table: where the (embedded) enclosing the entry will be stored
- * @out_entry: there the partition table entry number will be stored
- *
- * This function finds the entry that a certain byte of the disk belongs to.
- * As partition tables can be embedded (think MS-DOS extended partitions)
- * the returned partition table (out_part_table) might be different from
- * the one passed. If the offset belongs to a primary partition then the
- * return partition_table will be the same as the passed one.
- *
- * If there is no partition at the given offset (might be free space),
- * out_entry will be set to -1. Note that out_part_table will always
- * be set though and free space in the primary disk space and the
- * extended partition space differs.
- *
- * This is a convenience function.
- */
-void
-part_table_find (PartitionTable *part_table,
- guint64 offset,
- PartitionTable **out_part_table,
- int *out_entry);
-
-/**
- * part_table_entry_get_nested:
- * @part_table: the partition table
- * @entry: zero-based index of entry in partition table
- *
- * If the partition table entry points to an embedded partition table this
- * function will return a PartitionTable object representing it.
- *
- * Returns: NULL if the entry does not point to a an embedded partition table.
- * Do not free with part_table_free() - the object will be freed when
- * freeing the root object.
- */
-PartitionTable *
-part_table_entry_get_nested (PartitionTable *part_table,
- int entry);
-
-/**
- * part_table_entry_is_in_use:
- * @part_table: the partition table
- * @entry: zero-based index of entry in partition table
- *
- * Some partition table formats, notably PART_TYPE_MSDOS, has the
- * notion of unused partition table entries. For example it's
- * perfectly fine to only have /dev/sda being partitioned into
- * /dev/sda1 and /dev/sda3.
- *
- * This function determines whether a partition table entry is in use
- * or not.
- *
- * Returns: Whether the partition table entry is in use
- */
-gboolean
-part_table_entry_is_in_use (PartitionTable *part_table,
- int entry);
-
-/**
- * part_table_entry_get_type:
- * @part_table: the partition table
- * @entry: zero-based index of entry in partition table
- *
- * Get the partition table type - the type itself is partitioning scheme
- * specific as described below.
- *
- * For PART_TYPE_MSDOS and PART_TYPE_MSDOS_EXTENDED, the type is an integer
- * encoded in a string, e.g. 0x83 is Linux. Use atoi() to convert back to
- * an integer. See http://www.win.tue.nl/~aeb/partitions/partition_types-1.html
- * for details.
- *
- * For PART_TYPE_GPT, this is the GUID encoded as a string, see
- * http://en.wikipedia.org/wiki/GUID_Partition_Table for details.
- *
- * For PART_TYPE_APPLE, this is a string as defined in
- * http://developer.apple.com/documentation/mac/Devices/Devices-126.html.
- * For FAT file systems, it appears that "DOS_FAT_32", "DOS_FAT_16" and
- * "DOS_FAT_12" are also recognized under Mac OS X (I've tested this too) cf.
- * http://lists.apple.com/archives/Darwin-drivers/2003/May/msg00021.html
- *
- * Returns: The partition table type. Caller shall free this with g_free().
- */
-char *
-part_table_entry_get_type (PartitionTable *part_table,
- int entry);
-
-/**
- * part_table_entry_get_label:
- * @part_table: the partition table
- * @entry: zero-based index of entry in partition table
- *
- * Label of the partition. This is only supported for PART_TYPE_APPLE and
- * PART_TYPE_GPT. Note that this is not the same as the file system label
- * in a file system in the partition.
- *
- * Returns: The label or NULL if the partitioning scheme does not support
- * labels. Caller shall free this with g_free().
- */
-char *
-part_table_entry_get_label (PartitionTable *part_table,
- int entry);
-
-/**
- * part_table_entry_get_uuid:
- * @part_table: the partition table
- * @entry: zero-based index of entry in partition table
- *
- * Some UUID/GUID of the partition. This is only supported for PART_TYPE_GPT.
- *
- * Returns: The UUID or NULL if the partitioning scheme does not support
- * UUID/GUID. Caller shall free this with g_free().
- */
-char *
-part_table_entry_get_uuid (PartitionTable *part_table,
- int entry);
-
-/**
- * part_table_entry_get_flags:
- * @part_table: the partition table
- * @entry: zero-based index of entry in partition table
- *
- * Get flags of partition table entry. This is dependent on the partitioning
- * scheme.
- *
- * For PART_TYPE_MSDOS and PART_TYPE_MSDOS_EXTENDED the following flags are
- * recognized:
- * - "boot"; meaning that the bootable flag is set. This is used by some
- * BIOS'es and boot loaders to populate a boot menu.
- *
- * For PART_TYPE_GPT the following flags are recognized:
- * - "required" which corresponds to bit 0 of the attibutes
- * (offset 48), meaning "Required for the platform to function. The
- * system cannot function normally if this partition is removed. This
- * partition should be considered as part of the hardware of the
- * system, and if it is removed the system may not boot. It may
- * contain diagnostics, recovery tools, or other code or data that is
- * critical to the functioning of a system independent of any OS."
- *
- *
- * For PART_TYPE_APPLE the following flags are recognized:
- * - "allocated"; if the partition is already allocated
- * - "in_use"; if the partition is in use; may be cleared after a system reset
- * - "boot"; if partition contains valid boot information
- * - "allow_read"; if partition allows reading
- * - "allow_write"; if partition allows writing
- * - "boot_code_is_pic"; if boot code is position independent
- *
- * Returns: An array of strings, one per flag, terminated by NULL. Caller
- * shall free this with g_strfreev().
- */
-char **
-part_table_entry_get_flags (PartitionTable *part_table,
- int entry);
-
-/**
- * part_table_entry_get_offset:
- * @part_table: the partition table
- * @entry: zero-based index of entry in partition table
- *
- * Get offset from start of disk where partition starts (as referenced in the
- * partition table entry)
- *
- * Returns: offset, from start of disk, in bytes
- */
-guint64
-part_table_entry_get_offset (PartitionTable *part_table,
- int entry);
-
-/**
- * part_table_entry_get_size:
- * @part_table: the partition table
- * @entry: zero-based index of entry in partition table
- *
- * Get size of partition (as referenced in the partition table entry)
- *
- * Returns: size of partition, in bytes
- */
-guint64
-part_table_entry_get_size (PartitionTable *part_table,
- int entry);
-
-/**
- * part_create_partition_table:
- * @device: name of device file for entire disk, e.g. /dev/sda
- * @scheme: the partitioning scheme
- *
- * Create a new fresh partition on a disk.
- *
- * Returns: TRUE if the operation was succesful, otherwise FALSE
- */
-gboolean
-part_create_partition_table (char *device,
- PartitionScheme scheme);
-
-/**
- * part_add_partition:
- * @device: name of device file for entire disk, e.g. /dev/sda
- * @start: start offset of partition, in bytes
- * @size: size of partition, in bytes
- * @out_start: where partition will start, after satisfying disk geometry constraints
- * @out_size: size of partition, after satisfying disk geometry constraints
- * @type: the partition type as defined in part_table_entry_get_type()
- * @flags: the partition flags as defined in part_table_entry_get_flags()
- * @label: the partition label as defined in part_table_entry_get_label()
- * @geometry_hps: heads-per-sector used for LBA<->CHS conversions
- * @geometry_spt: sectors-per-track used for LBA<->CHS conversions
- * @poke_kernel: whether to update the kernels in-memory representation of
- * the partition table
- *
- * Adds a new partition to a disk.
- *
- * If geometry_hps and geomtry_spt are both positive, they will be
- * used as the geometry of the disk for CHS<->LBA conversions. Notably
- * this is only applicable for MSDOS / MSDOS_EXTENDED partition
- * tables. Also, in this case, geometry is enforced to ensure that
- * partitions start and end at cylinder boundaries.
- *
- * If either geometry_hps or geomtry_spt are zero, geometry is
- * simply ignored and partitions will only be aligned to blocks, e.g.
- * normally 512 byte boundaries.
- *
- * If both geometry_hps or geomtry_spt are -1, then geometry information
- * probed from existing partition table entries / file systems on the
- * disk. This is not always reliable.
- *
- * As such, the caller cannot always expect that the partition created
- * will be at the requested offset and size due to e.g. geometry and
- * block boundary alignment. Therefore, the start and size where the
- * partition ends up is passed in the out_start and out_size
- * arguments.
- *
- * As embedded partition tables are supported, the caller should use
- * part_table_find() in advance to make sure that the passed type,
- * label and flags match the (embedded) partition table that this
- * partition will be part of.
- *
- * To create an MSDOS extended partition table in a MSDOS partition
- * table, simply pass 0x05, 0x0f or 0x85 as the partition type.
- *
- * Unless @poke_kernel is set to #TRUE, in order for changes to take
- * effect, the caller needs to poke the OS kernel himself to make it
- * reload the partition table.
- *
- * NOTE: After calling this function you need to discard any partition table
- * obtained with part_table_load_from_disk() since the in-memory data structure
- * is not updated.
- *
- * Returns: TRUE if the operation was succesful, otherwise FALSE
- */
-gboolean
-part_add_partition (char *device,
- guint64 start,
- guint64 size,
- guint64 *out_start,
- guint64 *out_size,
- guint *out_num,
- char *type,
- char *label,
- char **flags,
- int geometry_hps,
- int geometry_spt,
- gboolean poke_kernel);
-
-/**
- * part_change_partition:
- * @device_file: name of device file for entire disk, e.g. /dev/sda
- * @start: start offset of existing partition, in bytes
- * @new_start: new start offset of partition, in bytes
- * @new_size: new size of partition, in bytes
- * @out_start: where partition will start, after satisfying disk geometry constraints
- * @out_size: size of partition, after satisfying disk geometry constraints
- * @type: the partition type as defined in part_table_entry_get_type() or NULL to not change
- * @flags: the partition flags as defined in part_table_entry_get_flags() or NULL to not change
- * @label: the partition label as defined in part_table_entry_get_label() or NULL to not change
- * @geometry_hps: heads-per-sector used for LBA<->CHS conversions
- * @geometry_spt: sectors-per-track used for LBA<->CHS conversions
- *
- * Changes an existing partition table entry on disk. The contents of
- * the partition will not be touched.
- *
- * XXX TODO FIXME: probably be careful with overlapping partitions as
- * e.g. extended MS-DOS partitions have the partition information just
- * before the partition data itself. Need to look into this.
- *
- * If new_start and new_size matches the existing start and size, only
- * flags, label and type are changed. Any of flags, label and type can
- * be set to NULL to signal there should be no change. Thus, this
- * function serves two purposes. It can be used to both change offset and/or
- * size and it can be used to change type and/or flags and/or label.
- *
- * See part_add_partition() for information about geometry_hps and
- * geometry_spt and how it affects the resulting partition offset and
- * size. This function gives one guarantee though: the resulting size
- * will never be smaller than the requested size. This is useful for
- * two-step operations by which a file system is first shrinked and
- * then the partition table is updated.
- *
- * In order for changes to take effect, the caller needs to poke the
- * OS kernel himself to make it reload the partition table. It is not
- * automatically done by this function.
- *
- * NOTE: After calling this function you need to discard any partition
- * table obtained with part_table_load_from_disk() since the in-memory
- * data structure is not updated.
- *
- * Returns: TRUE if the operation was succesful, otherwise FALSE
- */
-gboolean
-part_change_partition (char *device_file,
- guint64 start,
- guint64 new_start,
- guint64 new_size,
- guint64 *out_start,
- guint64 *out_size,
- char *type,
- char *label,
- char **flags,
- int geometry_hps,
- int geometry_spt);
-
-/**
- * part_del_partition:
- * @device: name of device file for entire disk, e.g. /dev/sda
- * @offset: offset of somewhere within the partition to delete, in bytes
- * @poke_kernel: whether to update the kernels in-memory representation of
- * the partition table
- *
- * Deletes a partition. Just pass the offset of the partition. If you
- * delete an extended partition all logical partitions will be deleted
- * too.
- *
- * NOTE: After calling this function you need to discard any partition table
- * obtained with part_table_load_from_disk() since the in-memory data structure
- * is not updated.
- *
- * Returns: TRUE if the operation was succesful, otherwise FALSE
- */
-gboolean
-part_del_partition (char *device,
- guint64 offset,
- gboolean poke_kernel);
-
-#endif /* PARTUTIL_H */
+++ /dev/null
-#!/bin/bash
-set -e
-
-DEVICE=$1
-read CURPASS
-read NEWPASS
-
-echo -e "$CURPASS\n$NEWPASS\n$NEWPASS\n" | /sbin/cryptsetup luksAddKey $DEVICE
-echo -e "$CURPASS\n$NEWPASS\n" | /sbin/cryptsetup luksRemoveKey $DEVICE
+++ /dev/null
-#!/bin/bash
-
-set -e
-
-MD_DEVICE=$1
-shift
-
-NEW_NUM_RAID_DEVICES=$1
-shift
-
-BACKUP_FILENAME=$1
-shift
-
-# TODO: disable bitmap if it exists and renable later
-
-for device in "$@" ; do
- mdadm $MD_DEVICE --add $device
-done
-
-mdadm --grow $MD_DEVICE --raid-devices $NEW_NUM_RAID_DEVICES --backup-file "$BACKUP_FILENAME"
-
#include "gposixsignal.h"
+#include <udisks/udisks.h>
+
/* ---------------------------------------------------------------------------------------------------- */
static GMainLoop *loop = NULL;
gpointer user_data)
{
g_print ("Connected to the system bus\n");
+
+ UDisksBlockDevice *b;
+ b = udisks_block_device_stub_new ();
+ g_dbus_interface_register_object (G_DBUS_INTERFACE (b),
+ connection,
+ "/devices/blah",
+ NULL);
}
static void
+++ /dev/null
-udisks-dm-export
-udisks-part-id
-udisks-probe-ata-smart
-udisks-probe-sas-expander
-
+++ /dev/null
-
-NULL =
-
-INCLUDES = \
- -I$(top_builddir)/src -I$(top_srcdir)/src \
- -DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
- -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
- -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
- -DPACKAGE_BIN_DIR=\""$(bindir)"\" \
- -DPACKAGE_LOCALSTATE_DIR=\""$(localstatedir)"\" \
- -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
- -DPACKAGE_LIB_DIR=\""$(libdir)"\" \
- -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
- $(DBUS_GLIB_CFLAGS) \
- $(POLKIT_GOBJECT_1_CFLAGS) \
- $(GUDEV_CFLAGS) \
- $(GLIB_CFLAGS) \
- $(GIO_CFLAGS)
-
-# TODO: ideally move most of this to udev and/or util-linux
-#
-
-udevhelperdir = $(slashlibdir)/udev
-udevhelper_PROGRAMS = udisks-part-id \
- udisks-dm-export \
- udisks-probe-ata-smart \
- udisks-probe-sas-expander \
- $(NULL)
-
-if HAVE_LVM2
-udevhelper_PROGRAMS += udisks-lvm-pv-export
-endif
-
-udisks_part_id_SOURCES = part-id.c
-udisks_part_id_CPPFLAGS = $(AM_CPPFLAGS) $(LIBUDEV_CFLAGS)
-udisks_part_id_LDADD = $(GLIB_LIBS) $(LIBUDEV_LIBS) $(top_builddir)/src/helpers/libpartutil.la
-
-udisks_dm_export_SOURCES = udisks-dm-export.c
-udisks_dm_export_CPPFLAGS = $(AM_CPPFLAGS) $(DEVMAPPER_CFLAGS) $(GLIB_CFLAGS)
-udisks_dm_export_LDADD = $(DEVMAPPER_LIBS) $(GLIB_LIBS)
-
-udisks_lvm_pv_export_SOURCES = udisks-lvm-pv-export.c
-udisks_lvm_pv_export_CPPFLAGS = $(AM_CPPFLAGS) $(DEVMAPPER_CFLAGS) $(LVM2_CFLAGS) $(GLIB_CFLAGS)
-udisks_lvm_pv_export_LDADD = $(DEVMAPPER_LIBS) $(LVM2_LIBS) $(GLIB_LIBS)
-
-udisks_probe_ata_smart_SOURCES = udisks-probe-ata-smart.c
-udisks_probe_ata_smart_CPPFLAGS = $(AM_CPPFLAGS) $(LIBATASMART_CFLAGS)
-udisks_probe_ata_smart_LDADD = $(LIBATASMART_LIBS)
-
-udisks_probe_sas_expander_SOURCES = udisks-probe-sas-expander.c
-udisks_probe_sas_expander_CPPFLAGS = $(AM_CPPFLAGS) $(GLIB_CFLAGS)
-udisks_probe_sas_expander_LDADD = $(GLIB_LIBS)
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2009 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <libudev.h>
-
-#include "helpers/partutil.h"
-
-static void
-usage (int argc,
- char *argv[])
-{
- execlp ("man", "man", "part_id", NULL);
- g_printerr ("Cannot show man page: %m\n");
- exit (1);
-}
-
-static gchar *
-decode_udev_encoded_string (const gchar *str)
-{
- GString *s;
- gchar *ret;
- const gchar *end_valid;
- guint n;
-
- s = g_string_new (NULL);
- for (n = 0; str[n] != '\0'; n++)
- {
- if (str[n] == '\\')
- {
- gint val;
-
- if (str[n + 1] != 'x' || str[n + 2] == '\0' || str[n + 3] == '\0')
- {
- g_print ("**** NOTE: malformed encoded string '%s'\n", str);
- break;
- }
-
- val = (g_ascii_xdigit_value (str[n + 2]) << 4) | g_ascii_xdigit_value (str[n + 3]);
-
- g_string_append_c (s, val);
-
- n += 3;
- }
- else
- {
- g_string_append_c (s, str[n]);
- }
- }
-
- if (!g_utf8_validate (s->str, -1, &end_valid))
- {
- g_print ("**** NOTE: The string '%s' is not valid UTF-8. Invalid characters begins at '%s'\n", s->str, end_valid);
- ret = g_strndup (s->str, end_valid - s->str);
- g_string_free (s, TRUE);
- }
- else
- {
- ret = g_string_free (s, FALSE);
- }
-
- return ret;
-}
-
-static int
-sysfs_get_int (const char *dir,
- const char *attribute)
-{
- int result;
- char *contents;
- char *filename;
-
- result = 0;
- filename = g_build_filename (dir, attribute, NULL);
- if (g_file_get_contents (filename, &contents, NULL, NULL))
- {
- result = strtol (contents, NULL, 0);
- g_free (contents);
- }
- g_free (filename);
-
- return result;
-}
-
-static guint64
-sysfs_get_uint64 (const char *dir,
- const char *attribute)
-{
- guint64 result;
- char *contents;
- char *filename;
-
- result = 0;
- filename = g_build_filename (dir, attribute, NULL);
- if (g_file_get_contents (filename, &contents, NULL, NULL))
- {
- result = strtoll (contents, NULL, 0);
- g_free (contents);
- }
- g_free (filename);
-
- return result;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static struct udev_device*
-get_udev_device_from_device_file (struct udev *udev,
- const gchar *device_file)
-{
- struct udev_device *device;
- struct stat statbuf;
-
- device = NULL;
-
- if (stat (device_file, &statbuf) != 0)
- {
- g_printerr ("Error statting %s: %m\n", device_file);
- goto out;
- }
-
- device = udev_device_new_from_devnum (udev, 'b', statbuf.st_rdev);
- if (device == NULL)
- {
- g_printerr ("Error getting udev device for %s: %m\n", device_file);
- goto out;
- }
-
- out:
- return device;
-}
-
-/**
- * get_part_table_device_file:
- * @given_device: udev_device for the device given on the command line
- * @given_device_file: the device file given on the command line
- * @out_partition_table_syspath: Return location for sysfs path of the slave the partition is for.
- * @out_offset: Return location for offset or %NULL.
- * @out_alignment_offset: Return location for alignment offset or %NULL.
- * @out_partition_number: Return location for partition number or %NULL.
- *
- * If @given_device is not a partition, returns a copy of its device file.
- *
- * Otherwise, returns the device file for the block device for which
- * @given_device is a partition of. Other data is returned in the
- * @out_ parameters.
- *
- * If something goes wrong, %NULL is returned.
- */
-static gchar *
-get_part_table_device_file (struct udev_device *given_device,
- const gchar *given_device_file,
- gchar **out_partition_table_syspath,
- guint64 *out_offset,
- guint64 *out_alignment_offset,
- guint *out_partition_number)
-{
- gchar *ret;
- guint64 offset;
- guint partition_number;
- const gchar *devpath;
- gchar *partition_table_syspath;
- guint64 alignment_offset;
-
- devpath = NULL;
- offset = 0;
- ret = NULL;
- partition_table_syspath = NULL;
- alignment_offset = 0;
-
- devpath = udev_device_get_syspath (given_device);
- if (devpath == NULL)
- goto out;
-
- partition_number = sysfs_get_int (devpath, "partition");
-
- /* find device file for partition table device */
- if (partition_number > 0)
- {
- struct udev_device *device;
- guint n;
-
- /* partition */
- partition_table_syspath = g_strdup (devpath);
- for (n = strlen (partition_table_syspath) - 1; partition_table_syspath[n] != '/'; n--)
- partition_table_syspath[n] = '\0';
- partition_table_syspath[n] = '\0';
-
- device = udev_device_new_from_syspath (udev_device_get_udev (given_device), partition_table_syspath);
- if (device == NULL)
- {
- g_printerr ("Error getting udev device for syspath %s: %m\n", partition_table_syspath);
- goto out;
- }
- ret = g_strdup (udev_device_get_devnode (device));
- udev_device_unref (device);
- if (ret == NULL)
- {
- /* This Should Not Happenâ„¢, but was reported in a distribution upgrade
- scenario, so handle it gracefully */
- g_printerr ("Error getting devnode from udev device path %s: %m\n", partition_table_syspath);
- goto out;
- }
- offset = sysfs_get_uint64 (devpath, "start") * 512;
-
- alignment_offset = sysfs_get_uint64 (devpath, "alignment_offset");
- }
- else
- {
- const char *targets_type;
- const char *encoded_targets_params;
-
- targets_type = g_getenv ("UDISKS_DM_TARGETS_TYPE");
- if (targets_type == NULL)
- targets_type = udev_device_get_property_value (given_device, "UDISKS_DM_TARGETS_TYPE");
- encoded_targets_params = g_getenv ("UDISKS_DM_TARGETS_PARAMS");
- if (encoded_targets_params == NULL)
- encoded_targets_params = udev_device_get_property_value (given_device, "UDISKS_DM_TARGETS_PARAMS");
-
- //g_printerr ("targets_type=`%s'\n", targets_type);
- //g_printerr ("encoded_targets_params=`%s'\n", encoded_targets_params);
-
- /* If we ever need this for other types than "linear", remember to update
- udisks-dm-export.c as well. */
- if (g_strcmp0 (targets_type, "linear") == 0)
- {
- gint partition_slave_major;
- gint partition_slave_minor;
- guint64 offset_sectors;
- gchar *targets_params;
-
- targets_params = decode_udev_encoded_string (encoded_targets_params);
- if (targets_params == NULL || sscanf (targets_params,
- "%d:%d\x20%" G_GUINT64_FORMAT,
- &partition_slave_major,
- &partition_slave_minor,
- &offset_sectors) != 3)
- {
- g_printerr ("Error decoding UDISKS_DM_TARGETS_PARAMS=`%s'\n", targets_params);
- }
- else
- {
- struct udev_device *mp_device;
-
- mp_device = udev_device_new_from_devnum (udev_device_get_udev (given_device),
- 'b', makedev (partition_slave_major,
- partition_slave_minor));
- if (mp_device != NULL)
- {
- const char *dm_name;
- gint n;
-
- /* now figure out the partition number... we infer this from DM_NAME */
- partition_number = 0;
- dm_name = g_getenv ("DM_NAME");
- if (dm_name == NULL)
- dm_name = udev_device_get_property_value (given_device, "DM_NAME");
- if (dm_name == NULL || strlen (dm_name) == 0)
- {
- g_printerr ("DM_NAME not available\n");
- goto out;
- }
- for (n = strlen (dm_name) - 1; n >= 0; n--)
- {
- if (!isdigit (dm_name[n]))
- break;
- }
- /* if we have a partition, set partition number and parent device */
- if (n > 0 && dm_name[n] == 'p')
- {
- partition_number = atoi (dm_name + n + 1);
- if (partition_number < 1)
- {
- g_printerr ("Error determining partition number from DM_NAME=`%s'\n", dm_name);
- goto out;
- }
-
- ret = g_strdup (udev_device_get_devnode (mp_device));
- offset = offset_sectors * 512;
-
- partition_table_syspath = g_strdup (udev_device_get_syspath (mp_device));
-
- udev_device_unref (mp_device);
- g_free (targets_params);
-
- /* TODO: set alignment_offset */
-
- goto out;
- }
- }
- }
- g_free (targets_params);
- }
-
- /* not a kernel partition */
- partition_table_syspath = g_strdup (devpath);
- ret = g_strdup (given_device_file);
- partition_number = 0;
- }
-
- out:
- if (out_offset != NULL)
- *out_offset = offset;
- if (out_partition_number != NULL)
- *out_partition_number = partition_number;
- if (out_partition_table_syspath != NULL)
- *out_partition_table_syspath = partition_table_syspath;
- else
- g_free (partition_table_syspath);
- if (out_alignment_offset != NULL)
- *out_alignment_offset = alignment_offset;
-
- return ret;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static guint
-count_entries (PartitionTable *pt)
-{
- guint ret;
- guint num_top_level;
- guint n;
-
- ret = 0;
-
- num_top_level = part_table_get_num_entries (pt);
- for (n = 0; n < num_top_level; n++)
- {
- PartitionTable *nested;
-
- if (part_table_entry_is_in_use (pt, n))
- ret++;
-
- nested = part_table_entry_get_nested (pt, n);
- if (nested != NULL)
- {
- ret += part_table_get_num_entries (nested);
- }
- }
-
- return ret;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-int
-main (int argc,
- char *argv[])
-{
- guint n;
- gint fd;
- gchar *devpath;
- const gchar *device_file;
- gchar *partition_table_device_file;
- struct udev *udev;
- struct udev_device *device;
- PartitionTable *partition_table;
- guint64 partition_offset;
- guint64 partition_alignment_offset;
- guint partition_number;
- gchar *partition_table_syspath;
-
- udev = NULL;
- devpath = NULL;
- partition_table_device_file = NULL;
- partition_table_syspath = NULL;
- partition_table = NULL;
-
- udev = udev_new ();
- if (udev == NULL)
- {
- g_printerr ("Error initializing libudev: %m\n");
- goto out;
- }
-
- device_file = NULL;
- for (n = 1; n < (guint) argc; n++)
- {
- if (strcmp (argv[n], "--help") == 0)
- {
- usage (argc, argv);
- return 0;
- }
- else
- {
- if (device_file != NULL)
- usage (argc, argv);
- device_file = argv[n];
- }
- }
-
- if (device_file == NULL)
- {
- g_printerr ("no device\n");
- goto out;
- }
-
- device = get_udev_device_from_device_file (udev, device_file);
-
- partition_table_device_file = get_part_table_device_file (device,
- device_file,
- &partition_table_syspath,
- &partition_offset,
- &partition_alignment_offset,
- &partition_number);
-
- g_printerr ("using device_file=%s syspath=%s, offset=%" G_GUINT64_FORMAT " ao=%" G_GUINT64_FORMAT " and number=%d for %s\n",
- partition_table_device_file,
- partition_table_syspath,
- partition_offset,
- partition_alignment_offset,
- partition_number,
- device_file);
-
- fd = open (partition_table_device_file, O_RDONLY);
- if (fd < 0)
- {
- g_printerr ("Error opening %s: %m\n", partition_table_device_file);
- goto out;
- }
- partition_table = part_table_load_from_disk (fd);
- if (partition_table == NULL)
- {
- g_printerr ("No partition table found on %s: %m\n", partition_table_device_file);
- goto out;
- }
- close (fd);
-
- if (partition_offset > 0)
- {
- PartitionTable *partition_table_for_entry;
- gint entry_num;
- gchar *type;
- gchar *label;
- gchar *uuid;
- gchar **flags;
- gchar *flags_combined;
- guint64 size;
-
- /* partition */
- part_table_find (partition_table, partition_offset, &partition_table_for_entry, &entry_num);
- if (entry_num == -1)
- {
- g_printerr ("Error finding partition at offset %" G_GUINT64_FORMAT " on %s\n",
- partition_offset,
- partition_table_device_file);
- goto out;
- }
-
- type = part_table_entry_get_type (partition_table_for_entry, entry_num);
- label = part_table_entry_get_label (partition_table_for_entry, entry_num);
- uuid = part_table_entry_get_uuid (partition_table_for_entry, entry_num);
- flags = part_table_entry_get_flags (partition_table_for_entry, entry_num);
- size = part_table_entry_get_size (partition_table_for_entry, entry_num);
-
- flags_combined = g_strjoinv (" ", flags);
-
- g_print ("UDISKS_PARTITION=1\n");
- g_print ("UDISKS_PARTITION_SCHEME=%s\n",
- //part_get_scheme_name (part_table_get_scheme (partition_table_for_entry)));
- part_get_scheme_name (part_table_get_scheme (partition_table)));
- g_print ("UDISKS_PARTITION_NUMBER=%d\n", partition_number);
- g_print ("UDISKS_PARTITION_TYPE=%s\n", type != NULL ? type : "");
- g_print ("UDISKS_PARTITION_SIZE=%" G_GINT64_FORMAT "\n", size);
- g_print ("UDISKS_PARTITION_LABEL=%s\n", label != NULL ? label : "");
- g_print ("UDISKS_PARTITION_UUID=%s\n", uuid != NULL ? uuid : "");
- g_print ("UDISKS_PARTITION_FLAGS=%s\n", flags_combined);
- g_print ("UDISKS_PARTITION_SLAVE=%s\n", partition_table_syspath);
- g_print ("UDISKS_PARTITION_OFFSET=%" G_GUINT64_FORMAT "\n", partition_offset);
- g_print ("UDISKS_PARTITION_ALIGNMENT_OFFSET=%" G_GUINT64_FORMAT "\n", partition_alignment_offset);
-
- g_free (type);
- g_free (label);
- g_free (uuid);
- g_strfreev (flags);
- g_free (flags_combined);
- }
- else
- {
- /* We need to be careful here: a VFAT header matches the specs for a
- * partitionless MBR header, so we must not advertise a VFAT device as a
- * partition table; in general, if we already know that a device has a
- * file system, it can't also be a partition table. */
-
- const char* fs = NULL;
- fs = g_getenv ("ID_FS_TYPE");
- if (fs == NULL)
- fs = udev_device_get_property_value (device, "ID_FS_TYPE");
- if (fs == NULL || *fs == '\0')
- {
- g_print ("UDISKS_PARTITION_TABLE=1\n");
- g_print ("UDISKS_PARTITION_TABLE_SCHEME=%s\n", part_get_scheme_name (part_table_get_scheme (partition_table)));
- g_print ("UDISKS_PARTITION_TABLE_COUNT=%d\n", count_entries (partition_table));
- }
- }
-
- out:
- g_free (devpath);
- g_free (partition_table_device_file);
- g_free (partition_table_syspath);
- if (partition_table != NULL)
- part_table_free (partition_table);
- if (udev != NULL)
- udev_unref (udev);
-
- return 0;
-}
-
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <libdevmapper.h>
-
-static void
-usage (void)
-{
- g_printerr ("incorrect usage\n");
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-
-/* This code is from udev - will become public libudev API at some point */
-
-/* count of characters used to encode one unicode char */
-static int utf8_encoded_expected_len(const char *str)
-{
- unsigned char c = (unsigned char)str[0];
-
- if (c < 0x80)
- return 1;
- if ((c & 0xe0) == 0xc0)
- return 2;
- if ((c & 0xf0) == 0xe0)
- return 3;
- if ((c & 0xf8) == 0xf0)
- return 4;
- if ((c & 0xfc) == 0xf8)
- return 5;
- if ((c & 0xfe) == 0xfc)
- return 6;
- return 0;
-}
-
-/* decode one unicode char */
-static int utf8_encoded_to_unichar(const char *str)
-{
- int unichar;
- int len;
- int i;
-
- len = utf8_encoded_expected_len(str);
- switch (len) {
- case 1:
- return (int)str[0];
- case 2:
- unichar = str[0] & 0x1f;
- break;
- case 3:
- unichar = (int)str[0] & 0x0f;
- break;
- case 4:
- unichar = (int)str[0] & 0x07;
- break;
- case 5:
- unichar = (int)str[0] & 0x03;
- break;
- case 6:
- unichar = (int)str[0] & 0x01;
- break;
- default:
- return -1;
- }
-
- for (i = 1; i < len; i++) {
- if (((int)str[i] & 0xc0) != 0x80)
- return -1;
- unichar <<= 6;
- unichar |= (int)str[i] & 0x3f;
- }
-
- return unichar;
-}
-
-/* expected size used to encode one unicode char */
-static int utf8_unichar_to_encoded_len(int unichar)
-{
- if (unichar < 0x80)
- return 1;
- if (unichar < 0x800)
- return 2;
- if (unichar < 0x10000)
- return 3;
- if (unichar < 0x200000)
- return 4;
- if (unichar < 0x4000000)
- return 5;
- return 6;
-}
-
-/* check if unicode char has a valid numeric range */
-static int utf8_unichar_valid_range(int unichar)
-{
- if (unichar > 0x10ffff)
- return 0;
- if ((unichar & 0xfffff800) == 0xd800)
- return 0;
- if ((unichar > 0xfdcf) && (unichar < 0xfdf0))
- return 0;
- if ((unichar & 0xffff) == 0xffff)
- return 0;
- return 1;
-}
-
-/* validate one encoded unicode char and return its length */
-static int utf8_encoded_valid_unichar(const char *str)
-{
- int len;
- int unichar;
- int i;
-
- len = utf8_encoded_expected_len(str);
- if (len == 0)
- return -1;
-
- /* ascii is valid */
- if (len == 1)
- return 1;
-
- /* check if expected encoded chars are available */
- for (i = 0; i < len; i++)
- if ((str[i] & 0x80) != 0x80)
- return -1;
-
- unichar = utf8_encoded_to_unichar(str);
-
- /* check if encoded length matches encoded value */
- if (utf8_unichar_to_encoded_len(unichar) != len)
- return -1;
-
- /* check if value has valid range */
- if (!utf8_unichar_valid_range(unichar))
- return -1;
-
- return len;
-}
-
-static int is_whitelisted(char c, const char *white)
-{
- if ((c >= '0' && c <= '9') ||
- (c >= 'A' && c <= 'Z') ||
- (c >= 'a' && c <= 'z') ||
- strchr("#+-.:=@_", c) != NULL ||
- (white != NULL && strchr(white, c) != NULL))
- return 1;
- return 0;
-}
-
-/**
- * _udev_util_encode_string:
- * @str: input string to be encoded
- * @str_enc: output string to store the encoded input string
- * @len: maximum size of the output string, which may be
- * four times as long as the input string
- *
- * Encode all potentially unsafe characters of a string to the
- * corresponding hex value prefixed by '\x'.
- *
- * Returns: 0 if the entire string was copied, non-zero otherwise.
- */
-static int
-_udev_util_encode_string(const char *str, char *str_enc, size_t len)
-{
- size_t i, j;
-
- if (str == NULL || str_enc == NULL)
- return -1;
-
- for (i = 0, j = 0; str[i] != '\0'; i++) {
- int seqlen;
-
- seqlen = utf8_encoded_valid_unichar(&str[i]);
- if (seqlen > 1) {
- if (len-j < (size_t)seqlen)
- goto err;
- memcpy(&str_enc[j], &str[i], seqlen);
- j += seqlen;
- i += (seqlen-1);
- } else if (str[i] == '\\' || !is_whitelisted(str[i], NULL)) {
- if (len-j < 4)
- goto err;
- sprintf(&str_enc[j], "\\x%02x", (unsigned char) str[i]);
- j += 4;
- } else {
- if (len-j < 1)
- goto err;
- str_enc[j] = str[i];
- j++;
- }
- }
- if (len-j < 1)
- goto err;
- str_enc[j] = '\0';
- return 0;
-err:
- return -1;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-/* based on the export patch in https://bugzilla.redhat.com/show_bug.cgi?id=438604 */
-
-static int
-dm_export (int major, int minor)
-{
- gboolean ret;
- struct dm_task *dmt;
- void *next;
- uint64_t start, length;
- char *target_type;
- char *params;
- const char *name;
- struct dm_info info;
- GString *target_types_str;
- GString *start_str;
- GString *length_str;
- GString *params_str;
- gchar buf[4096];
-
- ret = FALSE;
- dmt = NULL;
-
- dmt = dm_task_create (DM_DEVICE_TABLE);
- if (dmt == NULL)
- {
- perror ("dm_task_create");
- goto out;
- }
-
- if (dm_task_set_major (dmt, major) == 0)
- {
- perror ("dm_task_set_major");
- goto out;
- }
-
- if (dm_task_set_minor (dmt, minor) == 0)
- {
- perror ("dm_task_set_minor");
- goto out;
- }
-
- if (dm_task_run (dmt) == 0)
- {
- perror ("dm_task_run");
- goto out;
- }
-
- if (dm_task_get_info (dmt, &info) == 0 || !info.exists)
- {
- perror ("dm_task_get_info");
- goto out;
- }
-
- name = dm_task_get_name (dmt);
- if (name == NULL)
- {
- perror ("dm_task_get_name");
- goto out;
- }
-
- if (!info.exists)
- {
- goto out;
- }
-
- if (info.target_count != -1)
- g_print ("UDISKS_DM_TARGETS_COUNT=%d\n", info.target_count);
-
- target_types_str = g_string_new (NULL);
- start_str = g_string_new (NULL);
- length_str = g_string_new (NULL);
- params_str = g_string_new (NULL);
-
- /* export all tables */
- next = NULL;
- do
- {
- next = dm_get_next_target (dmt, next, &start, &length, &target_type, ¶ms);
- if (target_type != NULL)
- {
- g_string_append (target_types_str, target_type);
- g_string_append_printf (start_str, "%" G_GUINT64_FORMAT, start);
- g_string_append_printf (length_str, "%" G_GUINT64_FORMAT, length);
- /* Set target_params for known-safe and known-needed target types only. In particular,
- * we must not export it for "crypto", since that would expose
- * information about the key. */
- if (g_strcmp0 (target_type, "linear") == 0 && params != NULL && strlen (params) > 0)
- {
- _udev_util_encode_string (params, buf, sizeof (buf));
- g_string_append (params_str, buf);
- }
- }
-
- if (next != NULL)
- {
- g_string_append_c (target_types_str, ' ');
- g_string_append_c (start_str, ' ');
- g_string_append_c (length_str, ' ');
- g_string_append_c (params_str, ' ');
- }
- }
- while (next != NULL);
-
- if (target_types_str->len > 0)
- g_print ("UDISKS_DM_TARGETS_TYPE=%s\n", target_types_str->str);
- if (start_str->len > 0)
- g_print ("UDISKS_DM_TARGETS_START=%s\n", start_str->str);
- if (length_str->len > 0)
- g_print ("UDISKS_DM_TARGETS_LENGTH=%s\n", length_str->str);
- if (params_str->len > 0)
- g_print ("UDISKS_DM_TARGETS_PARAMS=%s\n", params_str->str);
-
- g_string_free (target_types_str, TRUE);
- g_string_free (start_str, TRUE);
- g_string_free (length_str, TRUE);
- g_string_free (params_str, TRUE);
-
- ret = TRUE;
-
- out:
- if (dmt != NULL)
- dm_task_destroy(dmt);
- return ret;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-int
-main (int argc,
- char *argv[])
-{
- int ret;
- int major;
- int minor;
- char *endp;
-
- ret = 1;
-
- if (argc != 3)
- {
- usage ();
- goto out;
- }
-
- major = strtol (argv[1], &endp, 10);
- if (endp == NULL || *endp != '\0')
- {
- usage ();
- goto out;
- }
-
- minor = strtol (argv[2], &endp, 10);
- if (endp == NULL || *endp != '\0')
- {
- usage ();
- goto out;
- }
-
- /* First export generic information about the mapped device */
- if (!dm_export (major, minor))
- goto out;
-
- ret = 0;
-
- out:
- return ret;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <libdevmapper.h>
-
-#include <lvm2app.h>
-
-static void
-usage (void)
-{
- g_printerr ("incorrect usage\n");
-}
-
-const gchar *pv_uuid = NULL;
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static vg_t
-find_vg_for_pv_uuid (lvm_t lvm_ctx,
- const gchar *pv_uuid,
- pv_t *out_pv)
-{
- vg_t ret;
- struct dm_list *vg_names;
- struct lvm_str_list *str_list;
-
- ret = NULL;
-
- vg_names = lvm_list_vg_names (lvm_ctx);
- dm_list_iterate_items (str_list, vg_names)
- {
- vg_t vg;
-
- vg = lvm_vg_open (lvm_ctx, str_list->str, "r", 0);
- if (vg != NULL)
- {
- struct dm_list *pvs;
-
- pvs = lvm_vg_list_pvs (vg);
- if (pvs != NULL)
- {
- struct lvm_pv_list *pv_list;
- dm_list_iterate_items (pv_list, pvs)
- {
- const char *uuid;
- pv_t pv = pv_list->pv;
-
- uuid = lvm_pv_get_uuid (pv);
- if (uuid != NULL)
- {
- if (g_strcmp0 (uuid, pv_uuid) == 0)
- {
- if (out_pv != NULL)
- *out_pv = pv;
- ret = vg;
- goto out;
- }
- }
- }
- }
-
- lvm_vg_close (vg);
- }
- }
-
- out:
- return ret;
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static void
-print_vg (vg_t vg)
-{
- const char *s;
- struct dm_list *pvs;
- struct dm_list *lvs;
-
- s = lvm_vg_get_uuid (vg); g_print ("UDISKS_LVM2_PV_VG_UUID=%s\n", s);
- s = lvm_vg_get_name (vg); g_print ("UDISKS_LVM2_PV_VG_NAME=%s\n", s);
- g_print ("UDISKS_LVM2_PV_VG_SIZE=%" G_GUINT64_FORMAT "\n", lvm_vg_get_size (vg));
- g_print ("UDISKS_LVM2_PV_VG_FREE_SIZE=%" G_GUINT64_FORMAT "\n", lvm_vg_get_free_size (vg));
- g_print ("UDISKS_LVM2_PV_VG_EXTENT_SIZE=%" G_GUINT64_FORMAT "\n", lvm_vg_get_extent_size (vg));
- g_print ("UDISKS_LVM2_PV_VG_EXTENT_COUNT=%" G_GUINT64_FORMAT "\n", lvm_vg_get_extent_count (vg));
- g_print ("UDISKS_LVM2_PV_VG_SEQNUM=%" G_GUINT64_FORMAT "\n", lvm_vg_get_seqno (vg));
-
- /* First we print the PVs that is part of the VG. We need this information
- * because not all PVs may be available.
- *
- * The format used is a space-separated list of list of key value
- * pairs separated by a semicolon. Since no value can contain
- * the semicolon character we don't need to worry about escaping
- * anything
- *
- * The following keys are recognized:
- *
- * uuid: the UUID of the PV
- * size: the size of the PV (TODO: pending liblvm addition)
- * allocated_size: the allocated size of the PV (TODO: pending liblvm addition)
- *
- * Here's an example of a string with this information
- *
- */
- pvs = lvm_vg_list_pvs (vg);
- if (pvs != NULL)
- {
- GString *str;
- struct lvm_pv_list *pv_list;
-
- str = g_string_new (NULL);
- dm_list_iterate_items (pv_list, pvs)
- {
- const char *uuid;
- guint64 size;
- guint64 free_size;
- pv_t pv = pv_list->pv;
-
- uuid = lvm_pv_get_uuid (pv);
- if (uuid != NULL)
- g_string_append_printf (str, "uuid=%s", uuid);
- size = lvm_pv_get_size (pv);
- g_string_append_printf (str, ";size=%" G_GUINT64_FORMAT, size);
- free_size = lvm_pv_get_free (pv);
- g_string_append_printf (str, ";allocated_size=%" G_GUINT64_FORMAT, size - free_size);
-
- g_string_append_c (str, ' ');
- }
- g_print ("UDISKS_LVM2_PV_VG_PV_LIST=%s\n", str->str);
- g_string_free (str, TRUE);
- }
-
- /* Then print the LVs that is part of the VG - we need this because
- * of the fact that LVs can be activated/deactivated independent of
- * each other.
- *
- * The format used is a space-separated list of list of key value
- * pairs separated by a semicolon. Since no value can contain
- * the semicolon character we don't need to worry about escaping
- * anything
- *
- * The following keys are recognized:
- *
- * uuid: the UUID of the LV
- * size: the size of the LV
- * name: the name of the LV
- * active: 1 if the LV is active (e.g. a mapped device exists) or 0 if the LV is inactive (no mapped device exists)
- *
- * Here's an example of a string with this information
- *
- * name=vg_test_lv1;uuid=rOHShU-4Qd4-Nvtl-gxdc-zpVr-cv5K-3H1Kzo;size=209715200;active=0 \
- * name=vg_test_lv2;uuid=YxV3GP-zOyg-TjeX-dGhp-E2Ws-OmwM-oJhGC6;size=314572800;active=0 \
- * name=vg_test_lv3;uuid=n43A2u-rKx5-sCPc-d5y5-XQmc-1ikS-K1srI4;size=314572800;active=0 \
- * name=lv4;uuid=Teb0lH-KFwr-R0pF-IbYX-WGog-E2Hs-ej20dP;size=1501560832;active=1
- *
- * At the same time, find the LV for this device
- */
- lvs = lvm_vg_list_lvs (vg);
- if (lvs != NULL)
- {
- GString *str;
- struct lvm_lv_list *lv_list;
-
- str = g_string_new (NULL);
- dm_list_iterate_items (lv_list, lvs)
- {
- const char *uuid;
- const char *name;
- gboolean is_active;
- guint64 size;
- lv_t lv = lv_list->lv;
-
- uuid = lvm_lv_get_uuid (lv);
- name = lvm_lv_get_name (lv);
- size = lvm_lv_get_size (lv);
- is_active = lvm_lv_is_active (lv) != 0 ? 1 : 0;
-
- if (uuid != NULL && name != NULL)
- {
- g_string_append_printf (str, "name=%s", name);
- g_string_append_c (str, ';');
- g_string_append_printf (str, "uuid=%s", uuid);
- g_string_append_c (str, ';');
- g_string_append_printf (str, "size=%" G_GUINT64_FORMAT ";", size);
- g_string_append_c (str, ';');
- g_string_append_printf (str, "active=%d", is_active);
- g_string_append_c (str, ' ');
- }
- }
- g_print ("UDISKS_LVM2_PV_VG_LV_LIST=%s\n", str->str);
- g_string_free (str, TRUE);
- }
-
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-static void
-print_pv (pv_t pv)
-{
- const char *s;
-
- s = lvm_pv_get_uuid (pv); g_print ("UDISKS_LVM2_PV_UUID=%s\n", s);
- g_print ("UDISKS_LVM2_PV_NUM_MDA=%" G_GUINT64_FORMAT "\n", lvm_pv_get_mda_count (pv));
-
- /* TODO: ask for more API in liblvm - pvdisplay(8) suggests more information
- * is available, e.g.
- *
- * --- Physical volume ---
- * PV Name /dev/sda2
- * VG Name vg_test_alpha
- * PV Size 1.82 GiB / not usable 3.08 MiB
- * Allocatable yes
- * PE Size 4.00 MiB
- * Total PE 464
- * Free PE 106
- * Allocated PE 358
- * PV UUID eWZFDe-3MmH-sWEs-a0Ni-DTwr-XMWL-9Frtot
- */
-}
-
-/* ---------------------------------------------------------------------------------------------------- */
-
-int
-main (int argc,
- char *argv[])
-{
- int ret;
- lvm_t lvm_ctx;
- vg_t vg;
- pv_t pv;
-
- ret = 1;
- lvm_ctx = NULL;
- vg = NULL;
-
- if (argc != 2)
- {
- usage ();
- goto out;
- }
-
- pv_uuid = (const gchar *) argv[1];
-
- lvm_ctx = lvm_init (NULL);
- if (lvm_ctx == NULL)
- {
- g_printerr ("Error calling lvm_init(): %m\n");
- goto out;
- }
-
- vg = find_vg_for_pv_uuid (lvm_ctx, pv_uuid, &pv);
- if (vg == NULL)
- {
- g_printerr ("Error finding VG for PV UUID %s\n", pv_uuid);
- goto out;
- }
-
- print_vg (vg);
- print_pv (pv);
-
- ret = 0;
-
- out:
- if (vg != NULL)
- lvm_vg_close (vg);
- if (lvm_ctx != NULL)
- lvm_quit (lvm_ctx);
- return ret;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2008 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <atasmart.h>
-
-static void
-usage (void)
-{
- fprintf (stderr, "incorrect usage\n");
-}
-
-int
-main (int argc,
- char *argv[])
-{
- int ret;
- const char *device;
- SkDisk *d;
- SkBool smart_is_available;
-
- d = NULL;
- ret = 1;
-
- if (argc != 2)
- {
- usage ();
- goto out;
- }
-
- device = argv[1];
-
- if (sk_disk_open (device, &d) < 0)
- {
- fprintf (stderr, "Failed to open disk %s: %s\n", device, strerror (errno));
- goto out;
- }
-
- if (sk_disk_smart_is_available (d, &smart_is_available) != 0)
- {
- fprintf (stderr, "Failed to determine if smart is available for %s: %s\n", device, strerror (errno));
- goto out;
- }
-
- printf ("UDISKS_ATA_SMART_IS_AVAILABLE=%d\n", smart_is_available);
-
- ret = 0;
-
- out:
- if (d != NULL)
- sk_disk_free (d);
- return ret;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2009 David Zeuthen <david@fubar.dk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-/* yeah, this is a bit cheesy with the spawning and the base64 encoding/decoding... once
- * smp_utils ships a library we'll just use that instead
- */
-
-#include <glib.h>
-
-static guchar *
-do_smp_command (const gchar *smp_command_line,
- gsize *out_smp_response_len)
-{
- guchar *ret;
- gchar *command_line;
- gchar *prog_stdout;
- gint prog_exit_status;
- GError *error;
-
- ret = NULL;
- error = NULL;
-
- command_line = g_strdup_printf ("sh -c '%s |base64 -w0'", smp_command_line);
- if (!g_spawn_command_line_sync (command_line, &prog_stdout, NULL, &prog_exit_status, &error))
- {
- g_printerr ("Error spawning `%s': %s", command_line, error->message);
- g_error_free (error);
- goto out;
- }
-
- if (!WIFEXITED (prog_exit_status))
- goto out;
-
- if (WEXITSTATUS (prog_exit_status) != 0)
- goto out;
-
- if (prog_stdout == NULL || strlen (prog_stdout) == 0)
- goto out;
-
- ret = g_base64_decode (prog_stdout, out_smp_response_len);
- if (ret == NULL)
- {
- g_printerr ("Error decoding SMP response\n");
- goto out;
- }
-
- out:
- g_free (command_line);
- g_free (prog_stdout);
- return ret;
-}
-
-gint
-main (int argc,
- char *argv[])
-{
- gint ret;
- gchar *basename;
- const gchar *sysfs_path;
- gchar *bsg_name;
- guchar *smp_response;
- gsize smp_response_len;
- gchar *s;
-
- ret = 1;
- basename = NULL;
- bsg_name = NULL;
- smp_response = NULL;
-
- if (argc != 2)
- {
- g_printerr ("Usage: %s <devpath>\n", argv[0]);
- goto out;
- }
- sysfs_path = argv[1];
-
- basename = g_path_get_basename (sysfs_path);
- bsg_name = g_strdup_printf ("/dev/bsg/%s", basename);
-
- s = g_strdup_printf ("smp_rep_manufacturer -r %s", bsg_name);
- smp_response = do_smp_command (s, &smp_response_len);
- g_free (s);
- if (smp_response == NULL)
- goto out;
-
- gchar *vendor;
- gchar *model;
- gchar *revision;
-
- /* 9.4.3.5 REPORT MANUFACTURER INFORMATION function:
- *
- * VENDOR IDENTIFICATION is 8 bytes of ASCII from bytes 12 through 19
- * PRODUCT IDENTIFICATION is 16 bytes of ASCII from bytes 20 through 35
- * PRODUCT REVISION LEVEL is 4 bytes of ASCII from bytes 36 through 39
- */
- vendor = g_strndup ((const gchar *) smp_response + 12, 8);
- model = g_strndup ((const gchar *) smp_response + 20, 16);
- revision = g_strndup ((const gchar *) smp_response + 36, 4);
-
- g_print ("ID_VENDOR=%s\n", vendor);
- g_print ("ID_MODEL=%s\n", model);
- g_print ("ID_REVISION=%s\n", revision);
-
- ret = 0;
-
- out:
- g_free (basename);
- g_free (bsg_name);
- g_free (smp_response);
- return ret;
-}
--- /dev/null
+## Process this file with automake to produce Makefile.in
+
+SUBDIRS =
+
+NULL =
+
+INCLUDES = \
+ -I$(top_builddir)/src -I$(top_srcdir)/src \
+ -DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
+ -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
+ -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
+ -DPACKAGE_BIN_DIR=\""$(bindir)"\" \
+ -DPACKAGE_LOCALSTATE_DIR=\""$(localstatedir)"\" \
+ -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
+ -DPACKAGE_LIB_DIR=\""$(libdir)"\" \
+ -D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT \
+ $(GLIB_CFLAGS) \
+ $(GIO_CFLAGS) \
+ $(NULL)
+
+generated-bindings.stamp : Makefile.am $(top_srcdir)/data/org.freedesktop.UDisks.xml
+ gdbus-codegen \
+ --strip-prefix org.freedesktop.UDisks. \
+ --namespace UDisks \
+ --output-prefix generated \
+ --include-dir udisks \
+ $(top_srcdir)/data/org.freedesktop.UDisks.xml \
+ $(NULL)
+
+BUILT_SOURCES = \
+ generated-bindings.stamp \
+ generated-bindings.h \
+ generated-bindingsprivate.h generated-bindingsprivate.c \
+ generated-marshallers.list \
+ generated-marshallers.h generated-marshallers.c \
+ generated-types.h \
+ generated-udisksblockdevice.h generated-udisksblockdevice.c \
+ $(NULL)
+
+lib_LTLIBRARIES=libudisks.la
+
+libudisksincludedir=$(includedir)/udisks-1.2/udisks
+libudisksinclude_HEADERS=
+ udisks.h \
+ generated-bindings.h \
+ generated-udisksblockdevice.h \
+ $(NULL)
+
+libudisks_la_SOURCES = \
+ $(BUILT_SOURCES) \
+ $(NULL)
+
+libudisks_la_CPPFLAGS = \
+ -DG_LOG_DOMAIN=\"libudisks\" \
+ $(AM_CPPFLAGS) \
+ $(NULL)
+
+libudisks_la_CFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(GIO_CFLAGS) \
+ $(NULL)
+
+libudisks_la_LIBADD = \
+ $(GLIB_LIBS) \
+ $(GIO_LIBS) \
+ $(NULL)
+
+# ----------------------------------------------------------------------------------------------------
+
+CLEANFILES = $(BUILT_SOURCES)
+
+EXTRA_DIST = \
+ $(NULL)
--- /dev/null
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2007-2010 David Zeuthen <zeuthen@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __UDISKS_H__
+#define __UDISKS_H__
+
+#ifndef UDISKS_API_IS_SUBJECT_TO_CHANGE
+#error libudisks is unstable API. You must define UDISKS_API_IS_SUBJECT_TO_CHANGE before including udisks/udisks.h
+#endif
+
+#include <udisks/generated-bindings.h>
+
+#endif /* __UDISKS_H__ */