delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2021/08/16/14:50:14

X-Recipient: archive-cygwin AT delorie DOT com
DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8220C3955433
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cygwin.com;
s=default; t=1629139812;
bh=HiG+1ttScJ1qnouQX5SEh69JfHGRp9KBoC37w1R72I4=;
h=Date:To:Subject:References:In-Reply-To:List-Id:List-Unsubscribe:
List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:
From;
b=HnqaNfPbb2DEIrpJsXfpjMFTIAzf5ePhvXzDjoPhO6NwtWuq0kpdXaBX9gxqelVNA
nFChj07wgarryXhk65TD5OpLMoWARJueDHQn1gxWmgDNuoOoBH5l+UK3uuTJU5G1nX
yfd6NkuabTvj3NNAIq/pEMN/q7NX8tgwnoxfmKd8=
X-Original-To: cygwin AT cygwin DOT com
Delivered-To: cygwin AT cygwin DOT com
DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5A84F385741D
Date: Mon, 16 Aug 2021 20:49:29 +0200
To: cygwin AT cygwin DOT com
Subject: Re: Duplicates in /proc/partitions
Message-ID: <YRqzOZAiDEfkHBM+@calimero.vinschen.de>
Mail-Followup-To: cygwin AT cygwin DOT com
References: <CAPJ9Yc8KMkmkCsZH7HwzHD59ju41L0svOcCskd3e0OG4qJ8Gxw AT mail DOT gmail DOT com>
<YRp7abUpIAqLCod3 AT calimero DOT vinschen DOT de>
<9a770c83-62ef-6849-16e7-e6956f4d2fab AT SystematicSw DOT ab DOT ca>
MIME-Version: 1.0
In-Reply-To: <9a770c83-62ef-6849-16e7-e6956f4d2fab@SystematicSw.ab.ca>
X-Provags-ID: V03:K1:anZahsGZr4n8opCH/ey8Vy+HXcVIPrvLqjiqiCZ18iMy/g5ziOA
LJ1WONM8xyS19o6LVymx1IEOTKzLHccgQJToCXfC+3rdVp6jSvJFaPvXX+Iz2hCuJONrJT7
ZyPmihER8DJg6jGbkDeYnANMQULW3IDxxT7ferex5oqDoivlSk1H6pTygfNGqi4mIsrkOFw
jBljd6XeVA99Zdb9wYa4A==
X-UI-Out-Filterresults: notjunk:1;V03:K0:tWrbgJR0t3I=:pt/MESdyyuoBaPaK/FXPm9
W3h1jlVR5FI91LQxyLN3QWNDHb0yny2xGQnb7yEEM2fNSsCb0okKFX+JwhqVbUSJjXQowRUnC
AEidPm9S3bCIj5GcsXgocgsSnsOFyqeVRruv73io9CjLvnxB4iCNV8LPTSfGuKHXSszYzMlA5
7fvvVe6Vb9n4U0WIdAsCV6ArQyoDwzeD97d2y4z2f/bCaXiQqXkmS27414Ictog3nCJ8fw0mH
ebl6sBGgLjXSKv7TsuCsxvObIlJ0visHSGcreiEgbFiJKxscebpju65qKendvGVuwwVh2PscE
YktrRxp1IeGJ40sOYkux6xfbRq8LShXCpR7+dkUc74Jvv5XTsQ/oeAZXC8CW23LKiuujy5rXz
is7v5k2jRzpn8diditDdL73Nwr1MnGWGy6n4iSV+0eT0wtprSSz/WnV7HfUtXkctJWmLWMTCQ
NyOZrcXHQAcp+ejKAzuAyyRDoiUzF6VqgHcfizcAvSPA/8TxJw96MyrmsXKHWJE1dENRhzZQt
kyPKMB72IeQw85frvmnpml5iYHSiZJJNRuiWus4sp6/4HnUCqCjiSo+TEPtCLQ9uQx4oB9iLo
MsRB6aXyMZqnWx9rJqTa37/siJylZHljSPJMogz7ORE6V2bPYbdf/nLxxzwPTgHS6/3G54an4
e/HxMn4u8sURK/Z89sKs73uko9qXLUrSYDZITHMS3CEJzC8EaGtEYoQDcuaiXvYYYwFfFfqG0
CiwteEr0uAH2S0rciVNnhs5TNUuK84LatCq36QtlX8E//zrfJtwcI6w5xtLmiB+8HZAkLVHN/
dp1VM7ZUcmPg/kSlquBY5oDt2QRvmfTKjE8ijBlrTX+w6ncc7SV+u1A1FbXbFwJM609SGJqkR
PDZDiqOATrXyHyvolADQ==
X-Spam-Status: No, score=-100.2 required=5.0 tests=BAYES_00,
GOOD_FROM_CORINNA_CYGWIN, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE,
RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NEUTRAL,
TXREP autolearn=ham autolearn_force=no version=3.4.4
X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on
server2.sourceware.org
X-BeenThere: cygwin AT cygwin DOT com
X-Mailman-Version: 2.1.29
List-Id: General Cygwin discussions and problem reports <cygwin.cygwin.com>
List-Unsubscribe: <https://cygwin.com/mailman/options/cygwin>,
<mailto:cygwin-request AT cygwin DOT com?subject=unsubscribe>
List-Archive: <https://cygwin.com/pipermail/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-request AT cygwin DOT com?subject=help>
List-Subscribe: <https://cygwin.com/mailman/listinfo/cygwin>,
<mailto:cygwin-request AT cygwin DOT com?subject=subscribe>
From: Corinna Vinschen via Cygwin <cygwin AT cygwin DOT com>
Reply-To: cygwin AT cygwin DOT com
Cc: Corinna Vinschen <corinna-cygwin AT cygwin DOT com>
Errors-To: cygwin-bounces+archive-cygwin=delorie DOT com AT cygwin DOT com
Sender: "Cygwin" <cygwin-bounces+archive-cygwin=delorie DOT com AT cygwin DOT com>

--kDBB+DwK7wZ8VEY6
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Aug 16 10:56, Brian Inglis wrote:
> On 2021-08-16 08:51, Corinna Vinschen via Cygwin wrote:
> > On Aug 13 12:56, David Bala=C5=BEic via Cygwin wrote:
> > > [...]
> > > $ cat /proc/partitions
> > > major minor  #blocks  name   win-mounts
> > >=20
> > >      8     0 1000204632 sda
> > >      8     1    102400 sda1
> > >      8     2     16384 sda2
> > >      8     3 999571820 sda3   C:\
> > >      8     4    510976 sda4
> > >      8    16  62522712 sdb
> > >      8    17   4096000 sdb1   D:\
> > >      8    18  58424664 sdb2
> > >      8    16  62522712 sdb
> > >      8    17   4096000 sdb1   D:\
> > >      8    18  58424664 sdb2   E:\
> > > [...]
> > > So the second listing shows sdb twice. Also E: does not seem to exi=
st
> > > (see below).
> >=20
> > So, second report.  Which OS is that on?  I don't have any physical
> > Windows machine anymore, so I have a bit of a problem to reproduce th=
is.
> >=20
> > As I wrote in https://cygwin.com/pipermail/cygwin/2021-August/249012.=
html,
> > I don't see how Cygwin would be able to duplicate entries, unless the=
 OS
> > itself duplicates entries.
> >=20
> > Somebody who can duplicate this issue would have to single step throu=
gh
> > function format_proc_partitions, see
> >=20
> > https://sourceware.org/git/?p=3Dnewlib-cygwin.git;a=3Dblob;f=3Dwinsup=
/cygwin/fhandler_proc.cc;h=3D66d19ab82f;hb=3DHEAD#l1686
> >=20
> > and check what actually happens in the above cases.
>=20
> Could those with the symptoms not provide useful information using a sc=
ript
> run in an elevated admin shell listing the relevant contents of Windows
> objects accessed by format_proc_partitions from /proc/sys/ similar to t=
he
> attached script and log from my system, where the correspondence is obv=
ious?

Not sure if that helps, but it's worth a try.

Other than that, I created a standalone application, shamelessly copying
the code from Cygwin's function format_proc_partitions() and tweaked it
to drop Cygwin internals.

The core of the function doesn't actually need Cygwin internals. It's
basically a double loop calling Windows functions and just using Cygwin
internals to print out major and minor numbers and the device name.  The
standalone application simply fakes those.

This allows any person who *can* reproduce the problem to run the code
under a debugger like GDB and debug what's going wrong.

I attached the code to this mail.  Store it under the name "proc_partitio=
n.c".  Compile it in two different ways, first with optimization:

$ gcc -g -O2 -o proc_partition_O2 proc_partition.c -lntdll

Run it:

$ ./proc_partition_O2

If the output contains duplicates, take a note, but otherwise
ignore it for now.

Next, build it without optimization for easier debugging:

$ gcc -g -o proc_partition proc_partition.c -lntdll

Run it:

$ ./proc_partition

If the output contains duplicates, great!  Now you can run it under
GDB and step through and see where it goes awry.  If it doesn't, you'll
have to debug the optimized version, which is sometimes a bit weird.
I'd be really glad if this allows us to reproduce the issue.

If none of them reproduces the issue... uhm... anyway, let's try first.


Thanks,
Corinna

--kDBB+DwK7wZ8VEY6
Content-Type: text/plain; charset=utf-8
Content-Disposition: attachment; filename="proc_partition.c"

#include <stdio.h>
#include <windows.h>
#include <winioctl.h>
#include <winternl.h>
#include <wchar.h>
#include <wctype.h>

NTSTATUS NTAPI NtOpenDirectoryObject (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
NTSTATUS NTAPI NtQueryDirectoryObject (HANDLE, PVOID, ULONG, BOOLEAN,
				       BOOLEAN, PULONG, PULONG);

typedef struct _DIRECTORY_BASIC_INFORMATION
{
  UNICODE_STRING ObjectName;
  UNICODE_STRING ObjectTypeName;
} DIRECTORY_BASIC_INFORMATION, *PDIRECTORY_BASIC_INFORMATION;

#define DIRECTORY_QUERY 1
#define NT_MAX_PATH	32768

char buf[NT_MAX_PATH];
char ioctl_buf[NT_MAX_PATH];
WCHAR mp_buf[NT_MAX_PATH];

typedef enum { false, true } bool;

int
main ()
{
  OBJECT_ATTRIBUTES attr;
  IO_STATUS_BLOCK io;
  NTSTATUS status;
  HANDLE dirhdl;
  WCHAR fpath[MAX_PATH];
  WCHAR gpath[MAX_PATH];
  DWORD len;

  /* Note that device ids and names are just faked here, not using the internal
     Cygwin code to generate device major/minor numbers and device names.
     There's *no* guarantee that the device name and the device major number
     is the same as in Cygwin. */
  char dev_name = '`';

  /* Open \Device object directory. */
  wchar_t wpath[MAX_PATH] = L"\\Device";
  UNICODE_STRING upath = {14, 16, wpath};

  InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
  status = NtOpenDirectoryObject (&dirhdl, DIRECTORY_QUERY, &attr);
  if (!NT_SUCCESS (status))
    {
      fprintf (stderr, "NtOpenDirectoryObject, status 0x%08x", status);
      return 1;
    }

  /* Traverse \Device directory ... */
  PDIRECTORY_BASIC_INFORMATION dbi = (PDIRECTORY_BASIC_INFORMATION)
				     alloca (640);
  BOOLEAN restart = TRUE;
  bool got_one = false;
  ULONG context = 0;
  while (NT_SUCCESS (NtQueryDirectoryObject (dirhdl, dbi, 640, TRUE, restart,
					     &context, NULL)))
    {
      HANDLE devhdl;
      PARTITION_INFORMATION_EX *pix = NULL;
      PARTITION_INFORMATION *pi = NULL;
      DWORD bytes_read;
      DWORD part_cnt = 0;
      unsigned long long size;

      restart = FALSE;
      /* ... and check for a "Harddisk[0-9]*" entry. */
      if (dbi->ObjectName.Length < 9 * sizeof (WCHAR)
	  || wcsncasecmp (dbi->ObjectName.Buffer, L"Harddisk", 8) != 0
	  || !iswdigit (dbi->ObjectName.Buffer[8]))
	continue;
      /* Got it.  Now construct the path to the entire disk, which is
	 "\\Device\\HarddiskX\\Partition0", and open the disk with
	 minimum permissions. */
      //unsigned long drive_num = wcstoul (dbi->ObjectName.Buffer + 8, NULL, 10);
      wcscpy (wpath, dbi->ObjectName.Buffer);
      PWCHAR wpart = wpath + dbi->ObjectName.Length / sizeof (WCHAR);
      wcpcpy (wpart, L"\\Partition0");
      upath.Length = dbi->ObjectName.Length + 22;
      upath.MaximumLength = upath.Length + sizeof (WCHAR);
      InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE,
				  dirhdl, NULL);
      status = NtOpenFile (&devhdl, READ_CONTROL, &attr, &io,
			   FILE_SHARE_VALID_FLAGS, 0);
      if (!NT_SUCCESS (status))
	{
	  fprintf (stderr, "NtOpenFile(%ls), status 0x%08x",
		   upath.Buffer, status);
	  continue;
	}
      if (!got_one)
	{
	  printf ("major minor  #blocks  name   win-mounts\n\n");
	  got_one = true;
	}
      /* Fetch partition info for the entire disk to get its size. */
      if (DeviceIoControl (devhdl, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0,
			   ioctl_buf, NT_MAX_PATH, &bytes_read, NULL))
	{
	  pix = (PARTITION_INFORMATION_EX *) ioctl_buf;
	  size = pix->PartitionLength.QuadPart;
	}
      else if (DeviceIoControl (devhdl, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0,
				ioctl_buf, NT_MAX_PATH, &bytes_read, NULL))
	{
	  pi = (PARTITION_INFORMATION *) ioctl_buf;
	  size = pi->PartitionLength.QuadPart;
	}
      else
	{
	  fprintf (stderr, "DeviceIoControl (%ls, "
		   "IOCTL_DISK_GET_PARTITION_INFO{_EX}) %lu",
		   upath.Buffer, (unsigned long) GetLastError ());
	  size = 0;
	}
      //device dev (drive_num, 0);
      ++dev_name;
      printf ("%5d %5d %9llu sd%c\n",
	      8, (dev_name - 'a') * 16, size >> 10, dev_name);

      /* Fetch drive layout info to get size of all partitions on the disk. */
      if (DeviceIoControl (devhdl, IOCTL_DISK_GET_DRIVE_LAYOUT_EX,
			   NULL, 0, ioctl_buf, NT_MAX_PATH, &bytes_read, NULL))
	{
	  PDRIVE_LAYOUT_INFORMATION_EX pdlix = (PDRIVE_LAYOUT_INFORMATION_EX)
					       ioctl_buf;
	  part_cnt = pdlix->PartitionCount;
	  pix = pdlix->PartitionEntry;
	}
      else if (DeviceIoControl (devhdl, IOCTL_DISK_GET_DRIVE_LAYOUT,
				NULL, 0, ioctl_buf, NT_MAX_PATH, &bytes_read, NULL))
	{
	  PDRIVE_LAYOUT_INFORMATION pdli = (PDRIVE_LAYOUT_INFORMATION) ioctl_buf;
	  part_cnt = pdli->PartitionCount;
	  pi = pdli->PartitionEntry;
	}
      else
	fprintf (stderr, "DeviceIoControl(%ls, "
		  "IOCTL_DISK_GET_DRIVE_LAYOUT{_EX}): %lu",
		  upath.Buffer, (unsigned long) GetLastError ());
      /* Loop over partitions. */
      if (pix || pi)
	for (DWORD i = 0; i < part_cnt && i < 64; ++i)
	  {
	    DWORD part_num;

	    if (pix)
	      {
		size = pix->PartitionLength.QuadPart;
		part_num = pix->PartitionNumber;
		++pix;
	      }
	    else
	      {
		size = pi->PartitionLength.QuadPart;
		part_num = pi->PartitionNumber;
		++pi;
	      }
	    /* A partition number of 0 denotes an extended partition or a
	       filler entry as described in fhandler_dev_floppy::lock_partition.
	       Just skip. */
	    if (part_num == 0)
	      continue;

	    //device dev (drive_num, part_num);
	    printf ("%5d %5d %9llu sd%c%d   ",
		    8, (dev_name - 'a') * 16 + part_num, size >> 10,
		    dev_name, part_num);
	    /* Check if the partition is mounted in Windows and, if so,
	       print the mount point list. */
	    swprintf (fpath, sizeof fpath,
		      L"\\\\?\\GLOBALROOT\\Device\\%ls\\Partition%u\\",
		      dbi->ObjectName.Buffer, part_num);
	    if (GetVolumeNameForVolumeMountPointW (fpath, gpath, MAX_PATH)
		&& GetVolumePathNamesForVolumeNameW (gpath, mp_buf,
						     NT_MAX_PATH, &len))
	      {
		for (PWCHAR p = mp_buf; *p; p = wcschr (p, L'\0') + 1)
		  printf (" %ls", p);
	      }
	    puts ("");
	  }
      NtClose (devhdl);
    }
  NtClose (dirhdl);

  if (!got_one)
    return 1;

  return 0;
}

--kDBB+DwK7wZ8VEY6
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline


-- 
Problem reports:      https://cygwin.com/problems.html
FAQ:                  https://cygwin.com/faq/
Documentation:        https://cygwin.com/docs.html
Unsubscribe info:     https://cygwin.com/ml/#unsubscribe-simple

--kDBB+DwK7wZ8VEY6--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019