bug-parted
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

DevFS and Partition Table Resync (PATCH)


From: Hong H. Pham
Subject: DevFS and Partition Table Resync (PATCH)
Date: Mon, 17 Dec 2001 14:54:26 -0500 (EST)

Hi Andrew,

When DevFS is active, after _disk_sync_part_table() has been called, the
partition table in /proc/partition is not correct, and the proper device
links in the /dev directory are not created.  This is actually a kernel
problem; the ioctl() handler for BLKPG_ADD_PARTITION in the kernel does
not notify the devfs system.  Note that the device path in
blkg_partition.devname, generated by _device_get_part_path(), is not used
by the kernel during the ioctl() call.

The work around for this is to check if DevFS is active, and if so,
_disk_sync_part_table() calls _kernel_reread_part_table() rather than
trying to resync the partition table.

I have included a patch (against libparted-1.5.5pre5) that addresses this
problem.  All the changes are to libparted/linux.c.  There are also some
minor enhancements.  A brief summary of the patch is below.

- Force reread of partition table if DevFS is active.
- added _have_devfs(), which checks if the system is using DevFS.
  Modified linux_disk_commit() and _device_get_part_path() to use this.
- modified _get_linux_version() to use uname(2), rather than probing
  /proc/sys/kernel/osrelease.  Kernel version checking is done using by
  using the KERNEL_VERSION() macro in <linux/version.h>
  Affected functions are _device_get_sector_size() and _have_blkpg().
- Modified linux_probe_all(); if _probe_proc_partitions() fail, resort
  to doing a blind device probe (_probe_standard_devices()).  Since
  /proc/partitions contains all the block devices and partitions that
  the kernel has detected and is currently using, I do not see why we
  have to waste time probing for devices that do not exist, or devices
  that have already been probed.  A few seconds in initialisation time
  can be saved if we avoid the blind device probe.

Cheers!
..h


diff -urN parted-1.5.5-pre5.old/libparted/linux.c 
parted-1.5.5-pre5/libparted/linux.c
--- parted-1.5.5-pre5.old/libparted/linux.c     Tue Nov 20 01:03:20 2001
+++ parted-1.5.5-pre5/libparted/linux.c Mon Dec 17 14:51:39 2001
@@ -32,8 +32,10 @@
 #include <sys/ioctl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/utsname.h>   /* for uname() */
 #include <linux/hdreg.h>
 #include <linux/unistd.h>
+#include <linux/version.h>
 #include <scsi/scsi.h>

 #include "blkpg.h"
@@ -254,6 +256,7 @@
        return 1;
 }

+#if 0
 static int
 _get_linux_version ()
 {
@@ -270,6 +273,43 @@

        return major * 0x100 + minor;
 }
+#endif
+
+static int
+_get_linux_version ()
+{
+       static int kver = -1;
+
+       struct utsname uts;
+       int major;
+       int minor;
+       int teeny;
+
+       if (kver != -1)
+               return kver;
+
+       uname (&uts);
+       if (sscanf (uts.release, "%u.%u.%u", &major, &minor, &teeny) != 3)
+               return kver = 0;
+
+       return kver = KERNEL_VERSION (major, minor, teeny);
+}
+
+static int
+_have_devfs ()
+{
+       static int have_devfs = -1;
+       struct stat sb;
+
+       if (have_devfs != -1)
+               return have_devfs;
+
+       /* the presence of /dev/.devfsd implies that DevFS is active */
+       if (stat("/dev/.devfsd", &sb) < 0 )
+               return have_devfs = 0;
+
+       return have_devfs = S_ISCHR(sb.st_mode) ? 1 : 0;
+}

 static int
 _device_get_sector_size (PedDevice* dev)
@@ -279,8 +319,13 @@

        PED_ASSERT (dev->open_count, return 0);

+#if 0
        if (_get_linux_version() < 0x203)    /* BLKSSZGET is broken < 2.3.x */
                return PED_SECTOR_SIZE;
+#endif
+       if (_get_linux_version() < KERNEL_VERSION (2,3,0))
+               return PED_SECTOR_SIZE;
+
        if (ioctl (arch_specific->fd, BLKSSZGET, &sector_size))
                return PED_SECTOR_SIZE;

@@ -1277,8 +1322,9 @@
 static void
 linux_probe_all ()
 {
-       _probe_proc_partitions ();
-       _probe_standard_devices ();
+       // HHP
+       if (!_probe_proc_partitions ())
+               _probe_standard_devices ();
 }

 static char*
@@ -1292,7 +1338,11 @@
                return NULL;

 #ifdef __linux__
+#if 0
+       // HHP
        if (strstr (dev->path, "disc"))         /* HACK: devfs */
+#endif
+       if (_have_devfs())
                snprintf (result, result_len, "%s/part%d", dev->path, num);
        else if (dev->type == PED_DEVICE_DAC960
                        || dev->type == PED_DEVICE_CPQARRAY
@@ -1589,6 +1639,8 @@
        return 1;
 }

+#if 0
+// HHP
 static int
 _have_blkpg ()
 {
@@ -1616,6 +1668,20 @@
 error:
        return 0;
 }
+#endif
+
+static int
+_have_blkpg ()
+{
+       static int have_blkpg = -1;
+       int        kver;
+
+       if (have_blkpg != -1)
+               return have_blkpg;
+
+       kver = _get_linux_version();
+       return have_blkpg = kver >= KERNEL_VERSION (2,4,0) ? 1 : 0;
+}

 static int
 linux_disk_commit (PedDisk* disk)
@@ -1623,7 +1689,13 @@
        if (!ped_device_sync (disk->dev))
                return 0;
        if (disk->dev->type != PED_DEVICE_FILE) {
-               if (_have_blkpg ())
+               /* The ioctl() command BLKPG_ADD_PARTITION does not notify
+                * the devfs system; consequently, /proc/partitions will not
+                * be up to date, and the proper links in /dev are not
+                * created.  Therefore, if using DevFS, we must get the kernel
+                * to re-read and grok the partition table.
+                */
+               if (_have_blkpg () && (!_have_devfs ()))
                        return _disk_sync_part_table (disk);
                else
                        return _kernel_reread_part_table (disk->dev);
diff -urN parted-1.5.5-pre5.old/parted.spec parted-1.5.5-pre5/parted.spec
--- parted-1.5.5-pre5.old/parted.spec   Sun Dec  2 04:43:22 2001
+++ parted-1.5.5-pre5/parted.spec       Wed Dec 31 19:00:00 1969
@@ -1,78 +0,0 @@
-%define        name    parted
-%define        ver     1.5.5-pre5
-%define        rel     1
-%define        prefix  /usr
-%define        sbindir /sbin
-%define mandir /usr/man
-%define aclocaldir     /usr/share/aclocal
-
-
-Summary                : flexible partitioning tool
-Name           : %{name}
-Version                : %{ver}
-Release                : %{rel}
-Source         : ftp://ftp.gnu.org/gnu/%{name}/%{name}-%{ver}.tar.gz
-Buildroot      : %{_tmppath}/%{name}-root
-Packager       : Fabian Emmes <address@hidden>
-Copyright      : GPL
-Group          : Applications/System
-Requires       : e2fsprogs, readline
-BuildPrereq    : e2fsprogs-devel, readline-devel
-%description
-GNU Parted is a program that allows you to create, destroy,
-resize, move and copy hard disk partitions. This is useful for
-creating space for new operating systems, reorganising disk
-usage, and copying data to new hard disks.
-
-
-%package devel
-Summary                : files required to compile software that uses libparted
-Group          : Development/System
-Requires       : e2fsprogs
-BuildPrereq    : e2fsprogs-devel, readline-devel
-%description devel
-This package includes the header files and libraries needed to
-statically link software with libparted.
-
-
-%prep
-%setup
-
-%build
-if [ -n "$LINGUAS" ]; then unset LINGUAS; fi
-%configure --prefix=%{prefix} --sbindir=%{sbindir}
-make
-
-
-%install
-rm -rf "$RPM_BUILD_ROOT"
-make DESTDIR="$RPM_BUILD_ROOT" install
-strip "${RPM_BUILD_ROOT}%{sbindir}"/parted
-
-
-%clean
-rm -rf "$RPM_BUILD_ROOT"
-
-
-%files
-%defattr(-,root,root)
-%doc AUTHORS BUGS COPYING ChangeLog NEWS README THANKS TODO doc/COPYING.DOC 
doc/API doc/USER doc/FAT
-%{prefix}/share/locale/*/*/*
-%{sbindir}/*
-%{mandir}/*/*
-%{prefix}/lib/*.so*
-
-
-%files devel
-%defattr(-,root,root)
-%{prefix}/include/*
-%{aclocaldir}/*
-%{prefix}/lib/*.a*
-%{prefix}/lib/*.la*
-
-%changelog
-* Mon Mar 13 2000 Fabian Emmes <address@hidden>
-- changed "unset LINGUAS" line
-- reintroduced %build section ;)
-- started changelog
-




reply via email to

[Prev in Thread] Current Thread [Next in Thread]