Package: parted
Version: 1.6.25.1-2
Severity: important
Tags: patch
Hi!
The attached patch adds GNU/kFreeBSD support to parted. It is based on a patch
for FreeBSD by Viktor Vasilev, from http://0xdeadc0de.net/v/parted/.
There's kfreebsd-gnu.diff (upstream stuff) and debian.diff for adding
libgeom-dev dependency in debian/control.
-- System Information:
Debian Release: testing/unstable
Architecture: kfreebsd-amd64 (x86_64)
Shell: /bin/sh linked to /bin/bash
Kernel: GNU/kFreeBSD 6.0-1-amd64-generic
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968) (ignored: LC_ALL set to C)
Versions of packages parted depends on:
ii libc0.1 2.3.6-7 GNU C Library: Shared libraries
ii libncurses5 5.5-1 Shared libraries for terminal hand
ii libparted1.6-13 1.6.25.1-2 The GNU Parted disk partitioning s
ii libreadline5 5.1-7 GNU readline and history libraries
parted recommends no packages.
-- no debconf information
diff -Nur parted-1.6.25.1.old/debian/control parted-1.6.25.1/debian/control
--- parted-1.6.25.1.old/debian/control 2006-04-18 20:42:06.000000000 +0200
+++ parted-1.6.25.1/debian/control 2006-04-18 20:42:45.000000000 +0200
@@ -4,7 +4,7 @@
Maintainer: Parted Maintainer Team <[EMAIL PROTECTED]>
Uploaders: Sven Luther <[EMAIL PROTECTED]>, Otavio Salvador <[EMAIL PROTECTED]>
Standards-Version: 3.6.2
-Build-Depends: debhelper (>= 4.2.0), dpatch, libncurses-dev | libncurses5-dev,
libreadline5-dev | libreadline-dev, uuid-dev, gettext, texinfo (>= 4.2),
debianutils (>= 1.13.1), autoconf, automake1.8, libtool
+Build-Depends: debhelper (>= 4.2.0), dpatch, libncurses-dev | libncurses5-dev,
libreadline5-dev | libreadline-dev, uuid-dev, gettext, texinfo (>= 4.2),
debianutils (>= 1.13.1), autoconf, automake1.8, libtool, libgeom-dev
[kfreebsd-i386 kfreebsd-amd64]
Package: parted
Architecture: any
diff -Nur parted-1.6.25.1.old/debian/control.in
parted-1.6.25.1/debian/control.in
--- parted-1.6.25.1.old/debian/control.in 2006-04-18 20:42:06.000000000
+0200
+++ parted-1.6.25.1/debian/control.in 2006-04-18 20:42:45.000000000 +0200
@@ -4,7 +4,7 @@
Maintainer: Parted Maintainer Team <[EMAIL PROTECTED]>
Uploaders: Sven Luther <[EMAIL PROTECTED]>, Otavio Salvador <[EMAIL PROTECTED]>
Standards-Version: 3.6.2
-Build-Depends: debhelper (>= 4.2.0), dpatch, libncurses-dev | libncurses5-dev,
libreadline5-dev | libreadline-dev, uuid-dev, gettext, texinfo (>= 4.2),
debianutils (>= 1.13.1), autoconf, automake1.8, libtool
+Build-Depends: debhelper (>= 4.2.0), dpatch, libncurses-dev | libncurses5-dev,
libreadline5-dev | libreadline-dev, uuid-dev, gettext, texinfo (>= 4.2),
debianutils (>= 1.13.1), autoconf, automake1.8, libtool, libgeom-dev
[kfreebsd-i386 kfreebsd-amd64]
Package: [EMAIL PROTECTED]@
Architecture: any
diff -Nur parted-1.6.25.1.old/configure.in parted-1.6.25.1/configure.in
--- parted-1.6.25.1.old/configure.in 2005-11-11 13:35:53.000000000 +0100
+++ parted-1.6.25.1/configure.in 2006-04-18 20:42:45.000000000 +0200
@@ -46,6 +46,8 @@
case "$host_os" in
linux*) OS=linux ;;
gnu*) OS=gnu ;;
+ freebsd* | kfreebsd*-gnu)
+ OS=freebsd ;;
*) AC_MSG_ERROR(
Unknown or unsupported OS \"$host_os\". Only linux and gnu are supported.
)
@@ -183,6 +185,7 @@
#include <sys/types.h>
#include <unistd.h>
])
+AC_CHECK_TYPE(loff_t, long long)
AM_ENABLE_SHARED
if test "$OS" = linux -a $ac_cv_sizeof_off_t -lt 8; then
@@ -341,6 +344,20 @@
LIBS="$OLD_LIBS"
fi
+dnl FreeBSD (and GNU/kFreeBSD):
+if test "$OS" = freebsd; then
+ CFLAGS="$CFLAGS -D_GNU_SOURCE=1"
+
+dnl libgeom
+ AC_CHECK_LIB(geom, gctl_get_handle,
+ OS_LIBS="$OS_LIBS -lgeom",
+ AC_MSG_ERROR(
+GNU Parted requires libgeom when running on FreeBSD or derivative systems.
+ )
+ exit
+ )
+fi
+
AC_SUBST(OS_LIBS)
dnl One day, gettext might support libtool...
@@ -362,7 +379,7 @@
exit
)
-AC_CHECK_HEADERS(getopt.h)
+AC_CHECK_HEADERS(getopt.h endian.h sys/endian.h)
dnl required for libparted/llseek.c (TODO: make linux-x86 only)
if test "$OS" = linux; then
diff -Nur parted-1.6.25.1.old/include/parted/Makefile.am parted-1.6.25.1/include/parted/Makefile.am
--- parted-1.6.25.1.old/include/parted/Makefile.am 2005-11-11 13:32:28.000000000 +0100
+++ parted-1.6.25.1/include/parted/Makefile.am 2006-04-18 20:42:45.000000000 +0200
@@ -1,6 +1,7 @@
partedincludedir = $(includedir)/parted
partedinclude_HEADERS = gnu.h \
linux.h \
+ freebsd.h \
constraint.h \
debug.h \
device.h \
diff -Nur parted-1.6.25.1.old/include/parted/freebsd.h parted-1.6.25.1/include/parted/freebsd.h
--- parted-1.6.25.1.old/include/parted/freebsd.h 1970-01-01 01:00:00.000000000 +0100
+++ parted-1.6.25.1/include/parted/freebsd.h 2006-04-18 20:44:08.000000000 +0200
@@ -0,0 +1,37 @@
+/*
+ libparted - a library for manipulating disk partitions
+ Copyright (C) 2001 Free Software Foundation, Inc.
+
+ 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 PED_FREEBSD_H_INCLUDED
+#define PED_FREEBSD_H_INCLUDED
+
+#include <parted/parted.h>
+#include <parted/device.h>
+
+#define FREEBSD_SPECIFIC(dev) ((FreeBSDSpecific*) (dev)->arch_specific)
+
+typedef struct _FreeBSDSpecific FreeBSDSpecific;
+
+struct _FreeBSDSpecific {
+ int fd;
+};
+
+extern PedArchitecture ped_freebsd_arch;
+
+#endif /* PED_FREEBSD_H_INCLUDED */
+
diff -Nur parted-1.6.25.1.old/libparted/Makefile.am parted-1.6.25.1/libparted/Makefile.am
--- parted-1.6.25.1.old/libparted/Makefile.am 2005-11-11 13:35:53.000000000 +0100
+++ parted-1.6.25.1/libparted/Makefile.am 2006-04-18 20:43:29.000000000 +0200
@@ -47,7 +47,8 @@
@[EMAIL PROTECTED]
EXTRA_libparted_la_SOURCES = linux.c \
- gnu.c
+ gnu.c \
+ freebsd.c
libparted_la_LIBADD = @UUID_LIBS@ \
@OS_LIBS@ \
diff -Nur parted-1.6.25.1.old/libparted/disk_bsd.c parted-1.6.25.1/libparted/disk_bsd.c
--- parted-1.6.25.1.old/libparted/disk_bsd.c 2005-11-11 13:35:53.000000000 +0100
+++ parted-1.6.25.1/libparted/disk_bsd.c 2006-04-18 20:42:45.000000000 +0200
@@ -24,6 +24,8 @@
#include <string.h>
+#include <sys/types.h>
+
#include <parted/parted.h>
#include <parted/debug.h>
#include <parted/endian.h>
diff -Nur parted-1.6.25.1.old/libparted/disk_sun.c parted-1.6.25.1/libparted/disk_sun.c
--- parted-1.6.25.1.old/libparted/disk_sun.c 2005-11-11 13:35:53.000000000 +0100
+++ parted-1.6.25.1/libparted/disk_sun.c 2006-04-18 20:42:45.000000000 +0200
@@ -24,6 +24,8 @@
#include <string.h>
+#include <sys/types.h>
+
#include <parted/parted.h>
#include <parted/debug.h>
#include <parted/endian.h>
diff -Nur parted-1.6.25.1.old/libparted/freebsd.c parted-1.6.25.1/libparted/freebsd.c
--- parted-1.6.25.1.old/libparted/freebsd.c 1970-01-01 01:00:00.000000000 +0100
+++ parted-1.6.25.1/libparted/freebsd.c 2006-04-18 20:44:08.000000000 +0200
@@ -0,0 +1,1009 @@
+/*
+ libparted - a library for manipulating disk partitions
+ Copyright (C) 1999 - 2005 Free Software Foundation, Inc.
+
+ 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 "config.h"
+
+#include <parted/parted.h>
+#include <parted/debug.h>
+#include <parted/freebsd.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <paths.h>
+#include <libgeom.h>
+#include <sys/param.h>
+#include <sys/ucred.h>
+#include <sys/mount.h>
+#include <sys/ioctl.h>
+#include <sys/sysctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/disk.h>
+#include <sys/ata.h>
+
+#if ENABLE_NLS
+# include <libintl.h>
+# define _(String) dgettext (PACKAGE, String)
+#else
+# define _(String) (String)
+#endif /* ENABLE_NLS */
+
+static char* _device_get_part_path (PedDevice* dev, int num);
+static int _partition_is_mounted_by_path (const char* path);
+
+static int
+_device_stat (PedDevice* dev, struct stat * dev_stat)
+{
+ PED_ASSERT (dev != NULL, return 0);
+ PED_ASSERT (!dev->external_mode, return 0);
+
+ while (1) {
+ if (!stat (dev->path, dev_stat)) {
+ return 1;
+ } else {
+ if (ped_exception_throw (
+ PED_EXCEPTION_ERROR,
+ PED_EXCEPTION_RETRY_CANCEL,
+ _("Could not stat device %s - %s."),
+ dev->path,
+ strerror (errno))
+ != PED_EXCEPTION_RETRY)
+ return 0;
+ }
+ }
+}
+
+static int
+_device_probe_type (PedDevice* dev)
+{
+ struct stat dev_stat;
+ char *np;
+ PedExceptionOption ex_status;
+
+ if (!_device_stat (dev, &dev_stat))
+ return 0;
+
+ if (!S_ISCHR(dev_stat.st_mode)) {
+ dev->type = PED_DEVICE_FILE;
+ return 1;
+ }
+
+ /* XXX guess if it's SCSI/ATA from the device name */
+ /* FreeBSD knows ad0/da0 */
+ np = strrchr(dev->path, '/');
+ if(np == NULL)
+ {
+ dev->type = PED_DEVICE_UNKNOWN;
+ return 0;
+ }
+ np += 1; /* advance past '/' */
+
+ if(strncmp(np, "ad", 2) == 0)
+ {
+ dev->type = PED_DEVICE_IDE;
+ }
+ else if(strncmp(np, "da", 2) == 0)
+ {
+ dev->type = PED_DEVICE_SCSI;
+ }
+ else
+ {
+ dev->type = PED_DEVICE_UNKNOWN;
+ }
+
+ return 1;
+}
+
+static int
+_device_get_sector_size (PedDevice* dev)
+{
+ FreeBSDSpecific* arch_specific = FREEBSD_SPECIFIC (dev);
+ u_int sector_size = PED_SECTOR_SIZE; /*makes Valgrind happy*/
+
+ PED_ASSERT (dev->open_count, return 0);
+
+ if (ioctl (arch_specific->fd, DIOCGSECTORSIZE, §or_size) == -1)
+ return PED_SECTOR_SIZE;
+
+ if (sector_size != PED_SECTOR_SIZE) {
+ if (ped_exception_throw (
+ PED_EXCEPTION_BUG,
+ PED_EXCEPTION_IGNORE_CANCEL,
+ _("The sector size on %s is %d bytes. Parted is known "
+ "not to work properly with drives with sector sizes "
+ "other than %d bytes."),
+ dev->path,
+ sector_size,
+ PED_SECTOR_SIZE)
+ == PED_EXCEPTION_IGNORE)
+ return sector_size;
+ else
+ return PED_SECTOR_SIZE;
+ }
+
+ return sector_size;
+}
+
+static PedSector
+_device_get_length (PedDevice* dev)
+{
+ FreeBSDSpecific* arch_specific = FREEBSD_SPECIFIC (dev);
+ off_t bytes = 0;
+
+ PED_ASSERT (dev->open_count > 0, return 0);
+
+ if(ioctl(arch_specific->fd, DIOCGMEDIASIZE, &bytes) == 0) {
+ return bytes / PED_SECTOR_SIZE;
+ }
+
+ return 0;
+}
+
+static int
+_device_probe_geometry (PedDevice* dev)
+{
+ FreeBSDSpecific* arch_specific = FREEBSD_SPECIFIC (dev);
+ struct stat dev_stat;
+ struct ata_params ap;
+
+ if (!_device_stat (dev, &dev_stat))
+ return 0;
+ PED_ASSERT (S_ISCHR (dev_stat.st_mode), return 0);
+
+ dev->length = _device_get_length (dev);
+ if (!dev->length)
+ return 0;
+
+ dev->sector_size = _device_get_sector_size (dev);
+ if (!dev->sector_size)
+ return 0;
+
+ dev->bios_geom.sectors = 63;
+ dev->bios_geom.heads = 255;
+ dev->bios_geom.cylinders
+ = dev->length / (63 * 255)
+ / (dev->sector_size / PED_SECTOR_SIZE);
+
+ if (0) /* disabled for 5.x compat by rmh -- if (ioctl (arch_specific->fd, IOCATAGPARM, &ap) == 0) */ {
+ dev->hw_geom.sectors = ap.sectors;
+ dev->hw_geom.heads = ap.heads;
+ dev->hw_geom.cylinders = ap.cylinders; /* XXX */
+/* dev->hw_geom.cylinders */
+/* = dev->length / (dev->hw_geom.heads */
+/* * dev->hw_geom.sectors) */
+/* / (dev->sector_size / PED_SECTOR_SIZE); */
+ } else {
+ dev->hw_geom = dev->bios_geom;
+ }
+
+ return 1;
+}
+
+static char*
+strip_name(char* str)
+{
+ int i;
+ int end = 0;
+
+ for (i = 0; str[i] != 0; i++) {
+ if (!isspace (str[i])
+ || (isspace (str[i]) && !isspace (str[i+1]) && str[i+1])) {
+ str [end] = str[i];
+ end++;
+ }
+ }
+ str[end] = 0;
+ return strdup (str);
+}
+
+static int
+init_ide (PedDevice* dev)
+{
+ FreeBSDSpecific* arch_specific = FREEBSD_SPECIFIC(dev);
+ struct stat dev_stat;
+ struct ata_params ap;
+ PedExceptionOption ex_status;
+ char vendor_buf[64];
+
+ if (!_device_stat (dev, &dev_stat))
+ goto error;
+
+ if (!ped_device_open (dev))
+ goto error;
+
+ if (1) /* disabled for 5.x compat by rmh -- if (ioctl (arch_specific->fd, IOCATAGPARM, &ap) == -1) */ {
+ ex_status = ped_exception_throw (
+ PED_EXCEPTION_WARNING,
+ PED_EXCEPTION_IGNORE_CANCEL,
+ _("Could not get identity of device %s - %s"),
+ dev->path, strerror (errno));
+ switch (ex_status) {
+ case PED_EXCEPTION_CANCEL:
+ goto error_close_dev;
+
+ case PED_EXCEPTION_UNHANDLED:
+ ped_exception_catch ();
+ case PED_EXCEPTION_IGNORE:
+ dev->model = strdup(_("IDE"));
+ }
+ } else {
+ snprintf(vendor_buf, 64, "%s/%s", ap.model, ap.revision);
+ dev->model = strip_name (vendor_buf);
+ }
+
+ if (!_device_probe_geometry (dev))
+ goto error_close_dev;
+
+ ped_device_close (dev);
+ return 1;
+
+error_close_dev:
+ ped_device_close (dev);
+error:
+ return 0;
+}
+
+static int
+init_file (PedDevice* dev)
+{
+ struct stat dev_stat;
+
+ if (!_device_stat (dev, &dev_stat))
+ goto error;
+ if (!ped_device_open (dev))
+ goto error;
+
+ if (S_ISCHR(dev_stat.st_mode))
+ dev->length = _device_get_length (dev);
+ else
+ dev->length = dev_stat.st_size / 512;
+ if (dev->length <= 0) {
+ ped_exception_throw (
+ PED_EXCEPTION_ERROR,
+ PED_EXCEPTION_CANCEL,
+ _("The device %s is zero-length, and can't possibly "
+ "store a file system or partition table. Perhaps "
+ "you selected the wrong device?"),
+ dev->path);
+ goto error_close_dev;
+ }
+
+ ped_device_close (dev);
+
+ dev->bios_geom.cylinders = dev->length / 4 / 32;
+ dev->bios_geom.heads = 4;
+ dev->bios_geom.sectors = 32;
+ dev->hw_geom = dev->bios_geom;
+ dev->sector_size = 512;
+ dev->model = strdup ("");
+ return 1;
+
+error_close_dev:
+ ped_device_close (dev);
+error:
+ return 0;
+}
+
+static int
+init_generic (PedDevice* dev, char* model_name)
+{
+ struct stat dev_stat;
+ PedExceptionOption ex_status;
+
+ if (!_device_stat (dev, &dev_stat))
+ goto error;
+
+ if (!ped_device_open (dev))
+ goto error;
+
+ ped_exception_fetch_all ();
+ if (_device_probe_geometry (dev)) {
+ ped_exception_leave_all ();
+ } else {
+ /* hack to allow use of files, for testing */
+ ped_exception_catch ();
+ ped_exception_leave_all ();
+
+ ex_status = ped_exception_throw (
+ PED_EXCEPTION_WARNING,
+ PED_EXCEPTION_IGNORE_CANCEL,
+ _("Unable to determine geometry of "
+ "file/device. You should not use Parted "
+ "unless you REALLY know what you're doing!"));
+ switch (ex_status) {
+ case PED_EXCEPTION_CANCEL:
+ goto error_close_dev;
+
+ case PED_EXCEPTION_UNHANDLED:
+ ped_exception_catch ();
+ case PED_EXCEPTION_IGNORE:
+ ; // just workaround for gcc 3.0
+ }
+
+ /* what should we stick in here? */
+ dev->length = dev_stat.st_size / PED_SECTOR_SIZE;
+ dev->bios_geom.cylinders = dev->length / 4 / 32;
+ dev->bios_geom.heads = 4;
+ dev->bios_geom.sectors = 32;
+ dev->sector_size = PED_SECTOR_SIZE;
+ }
+
+ dev->model = strdup (model_name);
+
+ ped_device_close (dev);
+ return 1;
+
+error_close_dev:
+ ped_device_close (dev);
+error:
+ return 0;
+}
+
+static PedDevice*
+freebsd_new (const char* path)
+{
+ PedDevice* dev;
+
+ PED_ASSERT (path != NULL, return NULL);
+
+ dev = (PedDevice*) ped_malloc (sizeof (PedDevice));
+ if (!dev)
+ goto error;
+
+ dev->path = strdup (path);
+ if (!dev->path)
+ goto error_free_dev;
+
+ dev->arch_specific
+ = (FreeBSDSpecific*) ped_malloc (sizeof (FreeBSDSpecific));
+ if (!dev->arch_specific)
+ goto error_free_path;
+
+ dev->open_count = 0;
+ dev->read_only = 0;
+ dev->external_mode = 0;
+ dev->dirty = 0;
+ dev->boot_dirty = 0;
+
+ if (!_device_probe_type (dev))
+ goto error_free_arch_specific;
+
+ switch (dev->type) {
+ case PED_DEVICE_IDE:
+ if (!init_ide (dev))
+ goto error_free_arch_specific;
+ break;
+
+ default:
+ ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
+ PED_EXCEPTION_CANCEL,
+ _("ped_device_new() Unsupported device type"));
+ goto error_free_arch_specific;
+ }
+ return dev;
+
+error_free_arch_specific:
+ ped_free (dev->arch_specific);
+error_free_path:
+ ped_free (dev->path);
+error_free_dev:
+ ped_free (dev);
+error:
+ return NULL;
+}
+
+static void
+freebsd_destroy (PedDevice* dev)
+{
+ ped_free (dev->arch_specific);
+ ped_free (dev->path);
+ ped_free (dev->model);
+ ped_free (dev);
+}
+
+static int
+freebsd_is_busy (PedDevice* dev)
+{
+ int i;
+ char* part_name;
+
+ if (_partition_is_mounted_by_path (dev->path))
+ return 1;
+
+ for (i = 0; i < 32; i++) {
+ int status;
+
+ part_name = _device_get_part_path (dev, i);
+ if (!part_name)
+ return 1;
+ status = _partition_is_mounted_by_path (part_name);
+ ped_free (part_name);
+
+ if (status)
+ return 1;
+ }
+
+ return 0;
+}
+
+/* we need to flush the master device, and all the partition devices,
+ * because there is no coherency between the caches.
+ * We should only flush unmounted partition devices, because:
+ * - there is never a need to flush them (we're not doing IO there)
+ * - flushing a device that is mounted causes unnecessary IO, and can
+ * even screw journaling & friends up. Even cause oopsen!
+ */
+
+/* XXX implement with an IOCATAREQUEST? */
+/* see ata_device_ioctl() */
+static void
+_flush_cache (PedDevice* dev)
+{
+/* FreeBSDSpecific* arch_specific = FREEBSD_SPECIFIC (dev); */
+/* int i; */
+
+/* if (dev->read_only) */
+/* return; */
+/* dev->dirty = 0; */
+
+/* ioctl (arch_specific->fd, BLKFLSBUF); */
+
+/* for (i = 1; i < 16; i++) { */
+/* char* name; */
+/* int fd; */
+
+/* name = _device_get_part_path (dev, i); */
+/* if (!name) */
+/* break; */
+/* if (!_partition_is_mounted_by_path (name)) { */
+/* fd = open (name, O_WRONLY, 0); */
+/* if (fd > 0) { */
+/* ioctl (fd, BLKFLSBUF); */
+/* close (fd); */
+/* } */
+/* } */
+/* ped_free (name); */
+/* } */
+}
+
+static int
+freebsd_open (PedDevice* dev)
+{
+ FreeBSDSpecific* arch_specific = FREEBSD_SPECIFIC (dev);
+
+retry:
+ arch_specific->fd = open (dev->path, O_RDWR);
+ if (arch_specific->fd == -1) {
+ char* rw_error_msg = strerror (errno);
+
+ arch_specific->fd = open (dev->path, O_RDONLY);
+ if (arch_specific->fd == -1) {
+ if (ped_exception_throw (
+ PED_EXCEPTION_ERROR,
+ PED_EXCEPTION_RETRY_CANCEL,
+ _("Error opening %s: %s"),
+ dev->path, strerror (errno))
+ != PED_EXCEPTION_RETRY) {
+ return 0;
+ } else {
+ goto retry;
+ }
+ } else {
+ ped_exception_throw (
+ PED_EXCEPTION_WARNING,
+ PED_EXCEPTION_OK,
+ _("Unable to open %s read-write (%s). %s has "
+ "been opened read-only."),
+ dev->path, rw_error_msg, dev->path);
+ dev->read_only = 1;
+ }
+ } else {
+ dev->read_only = 0;
+ }
+
+ _flush_cache (dev);
+
+ return 1;
+}
+
+static int
+freebsd_refresh_open (PedDevice* dev)
+{
+ return 1;
+}
+
+static int
+freebsd_close (PedDevice* dev)
+{
+ FreeBSDSpecific* arch_specific = FREEBSD_SPECIFIC (dev);
+
+ if (dev->dirty)
+ _flush_cache (dev);
+ close (arch_specific->fd);
+ return 1;
+}
+
+static int
+freebsd_refresh_close (PedDevice* dev)
+{
+ if (dev->dirty)
+ _flush_cache (dev);
+ return 1;
+}
+
+static int
+_device_seek (PedDevice* dev, PedSector sector)
+{
+ FreeBSDSpecific* arch_specific;
+ off_t pos;
+
+ PED_ASSERT (dev != NULL, return 0);
+ PED_ASSERT (!dev->external_mode, return 0);
+
+ arch_specific = FREEBSD_SPECIFIC (dev);
+
+ pos = sector * PED_SECTOR_SIZE;
+ return lseek (arch_specific->fd, pos, SEEK_SET) == pos;
+}
+
+static int
+freebsd_read (PedDevice* dev, void* buffer, PedSector start, PedSector count)
+{
+ FreeBSDSpecific* arch_specific = FREEBSD_SPECIFIC (dev);
+ int status;
+ PedExceptionOption ex_status;
+ size_t read_length = count * PED_SECTOR_SIZE;
+
+ while (1) {
+ if (_device_seek (dev, start))
+ break;
+
+ ex_status = ped_exception_throw (
+ PED_EXCEPTION_ERROR,
+ PED_EXCEPTION_RETRY_IGNORE_CANCEL,
+ _("%s during seek for read on %s"),
+ strerror (errno), dev->path);
+
+ switch (ex_status) {
+ case PED_EXCEPTION_IGNORE:
+ return 1;
+
+ case PED_EXCEPTION_RETRY:
+ break;
+
+ case PED_EXCEPTION_UNHANDLED:
+ ped_exception_catch ();
+ case PED_EXCEPTION_CANCEL:
+ return 0;
+ }
+ }
+
+ while (1) {
+ status = read (arch_specific->fd, buffer, read_length);
+ if (status == count * PED_SECTOR_SIZE) break;
+ if (status > 0) {
+ read_length -= status;
+ buffer += status;
+ continue;
+ }
+
+ ex_status = ped_exception_throw (
+ PED_EXCEPTION_ERROR,
+ PED_EXCEPTION_RETRY_IGNORE_CANCEL,
+ _("%s during read on %s"),
+ strerror (errno),
+ dev->path);
+
+ switch (ex_status) {
+ case PED_EXCEPTION_IGNORE:
+ return 1;
+
+ case PED_EXCEPTION_RETRY:
+ break;
+
+ case PED_EXCEPTION_UNHANDLED:
+ ped_exception_catch ();
+ case PED_EXCEPTION_CANCEL:
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static int
+freebsd_write (PedDevice* dev, const void* buffer, PedSector start,
+ PedSector count)
+{
+ FreeBSDSpecific* arch_specific = FREEBSD_SPECIFIC (dev);
+ int status;
+ PedExceptionOption ex_status;
+ size_t write_length = count * PED_SECTOR_SIZE;
+
+ if (dev->read_only) {
+ if (ped_exception_throw (
+ PED_EXCEPTION_ERROR,
+ PED_EXCEPTION_IGNORE_CANCEL,
+ _("Can't write to %s, because it is opened read-only."),
+ dev->path)
+ != PED_EXCEPTION_IGNORE)
+ return 0;
+ else
+ return 1;
+ }
+
+ while (1) {
+ if (_device_seek (dev, start))
+ break;
+
+ ex_status = ped_exception_throw (
+ PED_EXCEPTION_ERROR, PED_EXCEPTION_RETRY_IGNORE_CANCEL,
+ _("%s during seek for write on %s"),
+ strerror (errno), dev->path);
+
+ switch (ex_status) {
+ case PED_EXCEPTION_IGNORE:
+ return 1;
+
+ case PED_EXCEPTION_RETRY:
+ break;
+
+ case PED_EXCEPTION_UNHANDLED:
+ ped_exception_catch ();
+ case PED_EXCEPTION_CANCEL:
+ return 0;
+ }
+ }
+
+#ifdef READ_ONLY
+ printf ("ped_device_write (\"%s\", %p, %d, %d)\n",
+ dev->path, buffer, (int) start, (int) count);
+#else
+ dev->dirty = 1;
+ while (1) {
+ status = write (arch_specific->fd, buffer, write_length);
+ if (status == count * PED_SECTOR_SIZE) break;
+ if (status > 0) {
+ write_length -= status;
+ buffer += status;
+ continue;
+ }
+
+ ex_status = ped_exception_throw (
+ PED_EXCEPTION_ERROR,
+ PED_EXCEPTION_RETRY_IGNORE_CANCEL,
+ _("%s during write on %s"),
+ strerror (errno), dev->path);
+
+ switch (ex_status) {
+ case PED_EXCEPTION_IGNORE:
+ return 1;
+
+ case PED_EXCEPTION_RETRY:
+ break;
+
+ case PED_EXCEPTION_UNHANDLED:
+ ped_exception_catch ();
+ case PED_EXCEPTION_CANCEL:
+ return 0;
+ }
+ }
+#endif /* !READ_ONLY */
+ return 1;
+}
+
+/* returns the number of sectors that are ok.
+ */
+static PedSector
+freebsd_check (PedDevice* dev, void* buffer, PedSector start, PedSector count)
+{
+ FreeBSDSpecific* arch_specific = FREEBSD_SPECIFIC (dev);
+ PedSector done = 0;
+ int status;
+
+ if (!_device_seek (dev, start))
+ return 0;
+
+ for (done = 0; done < count; done += status / PED_SECTOR_SIZE) {
+ status = read (arch_specific->fd, buffer,
+ (size_t) ((count-done) * PED_SECTOR_SIZE));
+ if (status < 0)
+ break;
+ }
+
+ return done;
+}
+
+static int
+_do_fsync (PedDevice* dev)
+{
+ FreeBSDSpecific* arch_specific = FREEBSD_SPECIFIC (dev);
+ int status;
+ PedExceptionOption ex_status;
+
+ while (1) {
+ status = fsync (arch_specific->fd);
+ if (status >= 0) break;
+
+ ex_status = ped_exception_throw (
+ PED_EXCEPTION_ERROR,
+ PED_EXCEPTION_RETRY_IGNORE_CANCEL,
+ _("%s during write on %s"),
+ strerror (errno), dev->path);
+
+ switch (ex_status) {
+ case PED_EXCEPTION_IGNORE:
+ return 1;
+
+ case PED_EXCEPTION_RETRY:
+ break;
+
+ case PED_EXCEPTION_UNHANDLED:
+ ped_exception_catch ();
+ case PED_EXCEPTION_CANCEL:
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int
+freebsd_sync (PedDevice* dev)
+{
+ PED_ASSERT (dev != NULL, return 0);
+ PED_ASSERT (!dev->external_mode, return 0);
+
+ if (dev->read_only)
+ return 1;
+ if (!_do_fsync (dev))
+ return 0;
+ _flush_cache (dev);
+ return 1;
+}
+
+static int
+freebsd_sync_fast (PedDevice* dev)
+{
+ PED_ASSERT (dev != NULL, return 0);
+ PED_ASSERT (!dev->external_mode, return 0);
+
+ if (dev->read_only)
+ return 1;
+ if (!_do_fsync (dev))
+ return 0;
+ /* no cache flush... */
+ return 1;
+}
+
+/* XXX code from /usr/src/lib/libdisk/disk.c */
+static int
+_probe_standard_devices ()
+{
+ char dev_name [16];
+ char dev_type [16];
+ char fullpath [256];
+ int ret;
+ char* conftxt;
+ char* cptr;
+ size_t txtsize;
+
+
+ ret = sysctlbyname("kern.geom.conftxt", NULL, &txtsize, NULL, 0);
+ if (ret) {
+ printf("kern.geom.conftxt sysctl not available, giving up!");
+ return 0;
+ }
+ conftxt = ped_malloc(txtsize+1);
+ if (conftxt == NULL) {
+ printf("cannot malloc memory for conftxt");
+ return 0;
+ }
+ ret = sysctlbyname("kern.geom.conftxt", conftxt, &txtsize, NULL, 0);
+ if (ret) {
+ printf("error reading kern.geom.conftxt from the system");
+ free (conftxt);
+ return 0;
+ }
+
+ cptr = conftxt;
+
+ while (sscanf (cptr, "%*d %s %s",
+ dev_type, dev_name) != EOF) {
+ if (strcmp(dev_type, "DISK") == 0)
+ {
+ strcpy (fullpath, _PATH_DEV);
+ strcat (fullpath, dev_name);
+ printf("FreeBSD: probing %s...\n", fullpath);
+ _ped_device_probe (fullpath);
+ }
+
+ cptr = strchr(cptr, '\n');
+ cptr++;
+ }
+
+ ped_free(conftxt);
+
+ return 1;
+}
+
+static void
+freebsd_probe_all ()
+{
+ _probe_standard_devices ();
+}
+
+static char*
+_device_get_part_path (PedDevice* dev, int num)
+{
+ int path_len = strlen (dev->path);
+ int result_len = path_len + 16;
+ char* result;
+
+ result = (char*) ped_malloc (result_len);
+ if (!result)
+ return NULL;
+
+ /* append slice number (ad0, partition 1 => ad0s1)*/
+ snprintf (result, result_len, "%ss%d", dev->path, num);
+
+ return result;
+}
+
+static char*
+freebsd_partition_get_path (const PedPartition* part)
+{
+ return _device_get_part_path (part->disk->dev, part->num);
+}
+
+/* XXX code from /usr/src/sbin/mount/mount.c:getmntpt() */
+static int
+_partition_is_mounted_by_path (const char *path)
+{
+ struct stat part_stat, mntdevstat;
+ struct statfs *mntbuf, *statfsp;
+ char *devname;
+ char device[256];
+ int mntsize, i;
+
+ if (stat (path, &part_stat) != 0)
+ return 0;
+
+ if (!S_ISCHR(part_stat.st_mode))
+ return 0;
+
+ mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
+ for (i = 0; i < mntsize; i++) {
+ statfsp = &mntbuf[i];
+ devname = statfsp->f_mntfromname;
+ if (*devname != '/') {
+ strcpy(device, _PATH_DEV);
+ strcat(device, devname);
+ strcpy(statfsp->f_mntfromname, device);
+ }
+ if (stat(devname, &mntdevstat) == 0 &&
+ mntdevstat.st_rdev == part_stat.st_rdev)
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+_partition_is_mounted (const PedPartition *part)
+{
+ dev_t dev;
+ if (!ped_partition_is_active (part))
+ return 0;
+
+ return _partition_is_mounted_by_path (part->disk->dev->path);
+}
+
+static int
+freebsd_partition_is_busy (const PedPartition* part)
+{
+ PedPartition* walk;
+
+ PED_ASSERT (part != NULL, return 0);
+
+ if (_partition_is_mounted (part))
+ return 1;
+ if (part->type == PED_PARTITION_EXTENDED) {
+ for (walk = part->part_list; walk; walk = walk->next) {
+ if (freebsd_partition_is_busy (walk))
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* XXX maybe read the MBR again and hand it over to geom? */
+static int
+_kernel_reread_part_table (PedDevice* dev)
+{
+ FreeBSDSpecific* arch_specific = FREEBSD_SPECIFIC (dev);
+ int retry_count = 5;
+ struct gctl_req *grq;
+ char mbr_buf[512];
+ const char *q;
+
+ sync();
+
+ freebsd_read (dev, mbr_buf, 0, 1);
+
+ grq = gctl_get_handle();
+ gctl_ro_param(grq, "verb", -1, "write MBR");
+ gctl_ro_param(grq, "class", -1, "MBR");
+ q = strrchr(dev->path, '/');
+ if (q == NULL)
+ q = dev->path;
+ else
+ q++;
+ gctl_ro_param(grq, "geom", -1, q);
+ gctl_ro_param(grq, "data", dev->sector_size, mbr_buf);
+ q = gctl_issue(grq);
+ if (q == NULL) {
+ gctl_free(grq);
+ return(0);
+ }
+
+ gctl_free(grq);
+
+ return 1;
+}
+
+static int
+freebsd_disk_commit (PedDisk* disk)
+{
+ if (disk->dev->type != PED_DEVICE_FILE)
+ return _kernel_reread_part_table (disk->dev);
+
+ return 1;
+}
+
+static PedDeviceArchOps freebsd_dev_ops = {
+ _new: freebsd_new,
+ destroy: freebsd_destroy,
+ is_busy: freebsd_is_busy,
+ open: freebsd_open,
+ refresh_open: freebsd_refresh_open,
+ close: freebsd_close,
+ refresh_close: freebsd_refresh_close,
+ read: freebsd_read,
+ write: freebsd_write,
+ check: freebsd_check,
+ sync: freebsd_sync,
+ sync_fast: freebsd_sync_fast,
+ probe_all: freebsd_probe_all
+};
+
+PedDiskArchOps freebsd_disk_ops = {
+ partition_get_path: freebsd_partition_get_path,
+ partition_is_busy: freebsd_partition_is_busy,
+ disk_commit: freebsd_disk_commit
+};
+
+PedArchitecture ped_freebsd_arch = {
+ dev_ops: &freebsd_dev_ops,
+ disk_ops: &freebsd_disk_ops
+};
diff -Nur parted-1.6.25.1.old/libparted/fs_xfs/platform_defs.h parted-1.6.25.1/libparted/fs_xfs/platform_defs.h
--- parted-1.6.25.1.old/libparted/fs_xfs/platform_defs.h 2005-11-11 13:34:47.000000000 +0100
+++ parted-1.6.25.1/libparted/fs_xfs/platform_defs.h 2006-04-18 20:42:45.000000000 +0200
@@ -35,10 +35,16 @@
#ifndef __XFS_PLATFORM_DEFS_H__
#define __XFS_PLATFORM_DEFS_H__
+#include "config.h"
+
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
-#include <endian.h>
+#if HAVE_ENDIAN_H
+# include <endian.h>
+#elif HAVE_SYS_ENDIAN_H
+# include <sys/endian.h>
+#endif
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
diff -Nur parted-1.6.25.1.old/libparted/libparted.c parted-1.6.25.1/libparted/libparted.c
--- parted-1.6.25.1.old/libparted/libparted.c 2005-11-11 13:35:53.000000000 +0100
+++ parted-1.6.25.1/libparted/libparted.c 2006-04-18 20:42:45.000000000 +0200
@@ -24,6 +24,8 @@
#ifdef linux
# include <parted/linux.h>
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+# include <parted/freebsd.h>
#else
# include <parted/gnu.h>
#endif
@@ -177,6 +179,8 @@
/* FIXME: a better way of doing this? */
#ifdef linux
ped_set_architecture (&ped_linux_arch);
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+ ped_set_architecture (&ped_freebsd_arch);
#else
ped_set_architecture (&ped_gnu_arch);
#endif