DaemonForums  

Go Back   DaemonForums > Miscellaneous > Programming

Programming C, bash, Python, Perl, PHP, Java, you name it.

Reply
 
Thread Tools Display Modes
  #1   (View Single Post)  
Old 11th July 2008
PeterSteele PeterSteele is offline
Port Guard
 
Join Date: Jul 2008
Posts: 43
Default How to get a list of volumes?

I can use the system call getmntinfo on a FreeBSD system to get a list of all mounted volumes, but how can I get a list that contains *all* volumes, even those that are not mounted? I cannot seem to find an equivalent to getmntinfo for this, but I assume there must be a system call to retrieve this information. Any pointers would be appreciated.
Reply With Quote
  #2   (View Single Post)  
Old 11th July 2008
BSDfan666 BSDfan666 is offline
Real Name: N/A, this is the interweb.
Banned
 
Join Date: Apr 2008
Location: Ontario, Canada
Posts: 2,223
Default

Wow that's strange terminology you use.

If you read sysctl(3), you'll find HW_DISKNAMES in the CTL_HW section.

You can view the currently detected devices via sysctl(8):
$ sysctl hw.disknames

It's quite trivial to write a program which prints the results as well.
Code:
#include <stdio.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <err.h>

int main(void) {
	int mib[2];
	size_t len;
	char *p;

	mib[0] = CTL_HW;
	mib[1] = HW_DISKNAMES;

	/* Determine how much space to allocate. */
	if (sysctl(mib, 2, NULL, &len, NULL, 0) == -1)
		err(1, "sysctl");

	if ((p = (char *)malloc(len)) == NULL)
		err(1, NULL);

	/* Populate the allocated area with the string returned
	 * by sysctl.
	 */
	if (sysctl(mib, 2, p, &len, NULL, 0) == -1)
		err(1, "sysctl");

	printf("%s\n", p);

	return 0;
}
EDIT: Doh! It would appear you're a FreeBSD user, somehow I didn't catch that in your first reply.. unfortunately it would seem FreeBSD has no equivalent sysctl member.

Last edited by BSDfan666; 11th July 2008 at 11:44 PM.
Reply With Quote
  #3   (View Single Post)  
Old 12th July 2008
PeterSteele PeterSteele is offline
Port Guard
 
Join Date: Jul 2008
Posts: 43
Default

That's unfortunate. I had started to get my hopes up when I started reading your reply. And then you ended it with a "psych!"



Thanks anyway. I'll keep looking...
Reply With Quote
  #4   (View Single Post)  
Old 13th July 2008
Dr_Death_UAE's Avatar
Dr_Death_UAE Dr_Death_UAE is offline
BSD Daemon
 
Join Date: Jul 2008
Posts: 9
Default

why not use df -ah df(1)
__________________
Theory is when you know all and nothing works.
Practice is when all works and nobody knows why.
In this case we have put together theory and practice: nothing works... and nobody knows why!
(Albert Einstein)
Reply With Quote
  #5   (View Single Post)  
Old 13th July 2008
BSDfan666 BSDfan666 is offline
Real Name: N/A, this is the interweb.
Banned
 
Join Date: Apr 2008
Location: Ontario, Canada
Posts: 2,223
Default

The user asked how to display all "unmounted" disk devices. (Well, volumes..).

In the end, I think parsing the dmesg output may be the only option... poor FreeBSD users.

EDIT: Strange, browsing the FreeBSD CVS I found that HW_DISKNAMES is defined in sysctl.h? It's not documented in the man page though... can anyone check and see if the above works?

Last edited by BSDfan666; 13th July 2008 at 05:29 PM.
Reply With Quote
  #6   (View Single Post)  
Old 13th July 2008
PeterSteele PeterSteele is offline
Port Guard
 
Join Date: Jul 2008
Posts: 43
Default

Well, for one thing I want a programmatic solution--some kind of system call that returns a list of structures, similar to getmntinfo(). But even if I was to use "df -ah" and capture/parse the output, it only lists information for mounted file systems. I want to get a list of all mounted *and* unmounted file systems.
Reply With Quote
  #7   (View Single Post)  
Old 13th July 2008
18Googol2's Avatar
18Googol2 18Googol2 is offline
Real Name: whoami
Spam Deminer
 
Join Date: Apr 2008
Location: pwd
Posts: 283
Default

Quote:
Originally Posted by BSDfan666 View Post
In the end, I think parsing the dmesg output may be the only option... poor FreeBSD users.
dmesg wont help. dmesg lists only drives, not volumes.

Quote:
EDIT: Strange, browsing the FreeBSD CVS I found that HW_DISKNAMES is defined in sysctl.h? It's not documented in the man page though... can anyone check and see if the above works?
Nope, the closest alternative would be:

%sysctl kern.disks

PeterSteele: The above command plus some sort of listing /dev/ad0*, /dev/da0*...would be a solution for you
Reply With Quote
  #8   (View Single Post)  
Old 13th July 2008
ephemera's Avatar
ephemera ephemera is offline
Knuth's homeboy
 
Join Date: Apr 2008
Posts: 537
Default

are you creating your own application?
if so, exactly what o/p do you want?

from what i understand this is going to be a non-trivial program.
Reply With Quote
  #9   (View Single Post)  
Old 14th July 2008
PeterSteele PeterSteele is offline
Port Guard
 
Join Date: Jul 2008
Posts: 43
Default

Well, we were originally using getmntinfo, but our requirements have changed and we cannot rely solely on getmntinfo, mainly because we are not automounting our filesystems any more. Instead we mount them programmatically after possibly repartitioning them based on parameters supplied by the user during OOB. But this is ultimately getting too deep into our application. From what I gather it seems I will have to explicitly look at /dev/ad* to determine what volumes are defined and then use ioctl calls to get further information on these unmounted volumes. There doesn't seem to be any equivalent to getmntinfo for unmounted volumes.
Reply With Quote
Old 14th July 2008
ocicat ocicat is offline
Administrator
 
Join Date: Apr 2008
Posts: 3,318
Default

Quote:
Originally Posted by PeterSteele View Post
There doesn't seem to be any equivalent to getmntinfo for unmounted volumes.
Mounted partitions have had to meet the requirements of a recognized filesystem & communication occurs along known paths. To communicate to physically attached, yet unmounted, devices means that you will have to devise a communication path including sophisticated error handling which will duplicate significant portions of the established filesystem. In other words, it will be easier to simply mount the drives in question.

It may be that you have valid reasons for not mounting what you want to query, but by going this route, you are taking on a lot of responsibility. The complexity of your application is now magnitudes more complicated.
Reply With Quote
Old 14th July 2008
lvlamb's Avatar
lvlamb lvlamb is offline
Real Name: Louis V. Lambrecht
Spam Deminer
 
Join Date: May 2008
Location: .be
Posts: 221
Default

man disklabel
FreeBSD current can list 26 labels (there aare only 26 letters in the alphabet, when do we switch to Mandarin ?)
OpenBSD only lists 8 (i to n) alien FSes autside of it's own volume.
__________________
da more I know I know I know nuttin'
Reply With Quote
Old 14th July 2008
PeterSteele PeterSteele is offline
Port Guard
 
Join Date: Jul 2008
Posts: 43
Default

I can appreciate that it appears we are making our lives more complex, but we have a custom application that uses raw partitions to store data on. The raw partitions are not formatted with a standard file system but instead something of our own creation. We do have some mounted file systems as well and we can get the information for those easy enough. It's these raw partitions that we looking for a way to query their size. The disklabel command looks to be sufficient for our purposes though. Thanks for the pointer.

Peter
Reply With Quote
Old 17th July 2008
ephemera's Avatar
ephemera ephemera is offline
Knuth's homeboy
 
Join Date: Apr 2008
Posts: 537
Default

i don't think that there is a convinient OS interface to get partition info.
Here's a program to display info about DOS partitions:
Code:
/*
 *         Display DOS partitions.
 *         (reference: fdisk & wikipedia)
 *
 *         Copyright: ephemera @ daemonforums.org
 */

#include <sys/types.h>
#include <sys/stat.h>

#include <fcntl.h>
#include <err.h>
#include <errno.h>
#include <libgen.h>
#include <paths.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define	SEC_SIZE  512
#define	NDOSPART  4
#define DOSPARTSIZE 16
#define DOSPARTOFF 446
#define PRT_FLAG  0
#define PRT_TYPE  4
#define PRT_START  8
#define PRT_SIZE  12

#define u32dec(v) (*(uint32_t *)(v))

static struct part_type {
        uint8_t	type;
        const char *name;
} part_types[] = {
         {0x00, "unused"}
        ,{0x01, "Primary DOS with 12 bit FAT"}
        ,{0x02, "XENIX / file system"}
        ,{0x03, "XENIX /usr file system"}
        ,{0x04, "Primary DOS with 16 bit FAT (< 32MB)"}
        ,{0x05, "Extended DOS"}
        ,{0x06, "Primary 'big' DOS (>= 32MB)"}
        ,{0x07, "OS/2 HPFS, NTFS, QNX-2 (16 bit) or Advanced UNIX"}
        ,{0x08, "AIX file system or SplitDrive"}
        ,{0x09, "AIX boot partition or Coherent"}
        ,{0x0A, "OS/2 Boot Manager, OPUS or Coherent swap"}
        ,{0x0B, "DOS or Windows 95 with 32 bit FAT"}
        ,{0x0C, "DOS or Windows 95 with 32 bit FAT (LBA)"}
        ,{0x0E, "Primary 'big' DOS (>= 32MB, LBA)"}
        ,{0x0F, "Extended DOS (LBA)"}
        ,{0x10, "OPUS"}
        ,{0x11, "OS/2 BM: hidden DOS with 12-bit FAT"}
        ,{0x12, "Compaq diagnostics"}
        ,{0x14, "OS/2 BM: hidden DOS with 16-bit FAT (< 32MB)"}
        ,{0x16, "OS/2 BM: hidden DOS with 16-bit FAT (>= 32MB)"}
        ,{0x17, "OS/2 BM: hidden IFS (e.g. HPFS)"}
        ,{0x18, "AST Windows swapfile"}
        ,{0x24, "NEC DOS"}
        ,{0x3C, "PartitionMagic recovery"}
        ,{0x39, "plan9"}
        ,{0x40, "VENIX 286"}
        ,{0x41, "Linux/MINIX (sharing disk with DRDOS)"}
        ,{0x42, "SFS or Linux swap (sharing disk with DRDOS)"}
        ,{0x43, "Linux native (sharing disk with DRDOS)"}
        ,{0x4D, "QNX 4.2 Primary"}
        ,{0x4E, "QNX 4.2 Secondary"}
        ,{0x4F, "QNX 4.2 Tertiary"}
        ,{0x50, "DM (disk manager)"}
        ,{0x51, "DM6 Aux1 (or Novell)"}
        ,{0x52, "CP/M or Microport SysV/AT"}
        ,{0x53, "DM6 Aux3"}
        ,{0x54, "DM6"}
        ,{0x55, "EZ-Drive (disk manager)"}
        ,{0x56, "Golden Bow (disk manager)"}
        ,{0x5c, "Priam Edisk (disk manager)"} /* according to S. Widlake */
        ,{0x61, "SpeedStor"}
        ,{0x63, "System V/386 (such as ISC UNIX), GNU HURD or Mach"}
        ,{0x64, "Novell Netware/286 2.xx"}
        ,{0x65, "Novell Netware/386 3.xx"}
        ,{0x70, "DiskSecure Multi-Boot"}
        ,{0x75, "PCIX"}
        ,{0x77, "QNX4.x"}
        ,{0x78, "QNX4.x 2nd part"}
        ,{0x79, "QNX4.x 3rd part"}
        ,{0x80, "Minix until 1.4a"}
        ,{0x81, "Minix since 1.4b, early Linux partition or Mitac disk manager"}
        ,{0x82, "Linux swap or Solaris x86"}
        ,{0x83, "Linux native"}
        ,{0x84, "OS/2 hidden C: drive"}
        ,{0x85, "Linux extended"}
        ,{0x86, "NTFS volume set??"}
        ,{0x87, "NTFS volume set??"}
        ,{0x93, "Amoeba file system"}
        ,{0x94, "Amoeba bad block table"}
        ,{0x9F, "BSD/OS"}
        ,{0xA0, "Suspend to Disk"}
        ,{0xA5, "FreeBSD/NetBSD/386BSD"}
        ,{0xA6, "OpenBSD"}
        ,{0xA7, "NeXTSTEP"}
        ,{0xA9, "NetBSD"}
        ,{0xAC, "IBM JFS"}
        ,{0xAF, "HFS+"}
        ,{0xB7, "BSDI BSD/386 file system"}
        ,{0xB8, "BSDI BSD/386 swap"}
        ,{0xBE, "Solaris x86 boot"}
        ,{0xBF, "Solaris x86 (new)"}
        ,{0xC1, "DRDOS/sec with 12-bit FAT"}
        ,{0xC4, "DRDOS/sec with 16-bit FAT (< 32MB)"}
        ,{0xC6, "DRDOS/sec with 16-bit FAT (>= 32MB)"}
        ,{0xC7, "Syrinx"}
        ,{0xDB, "CP/M, Concurrent CP/M, Concurrent DOS or CTOS"}
        ,{0xE1, "DOS access or SpeedStor with 12-bit FAT extended partition"}
        ,{0xE3, "DOS R/O or SpeedStor"}
        ,{0xE4, "SpeedStor with 16-bit FAT extended partition < 1024 cyl."}
        ,{0xEB, "BeOS file system"}
        ,{0xEE, "EFI GPT"}
        ,{0xEF, "EFI System Partition"}
        ,{0xF1, "SpeedStor"}
        ,{0xF2, "DOS 3.3+ Secondary"}
        ,{0xF4, "SpeedStor large partition"}
        ,{0xFE, "SpeedStor >1024 cyl. or LANstep"}
        ,{0xFF, "Xenix bad blocks table"}
};

static int		is_valid_br(const uint8_t *br);
static int		is_ext_prt(const uint8_t *prt);
static int		is_zero_prt(const uint8_t *pr);
static const char *	get_type(int type);
static void		printprt(int partno, const uint8_t *part);

int 
main(int argc, char *argv[])
{
	char	*disk;
	uint8_t	*mbr_prt_ent, *ebr_prt_ent;
	uint8_t	mbr[SEC_SIZE], ebr[SEC_SIZE];
	int	i, fd, lpcnt;
	off_t	ebr_first, ebr_nxt;


	if (argc < 2) {
		fprintf(stderr, "Usage: %s disk\n", basename(argv[0]));
		exit(1);
	}

	disk = malloc(sizeof(_PATH_DEV) + strlen(argv[1]));
	sprintf(disk, "%s%s", argv[1][0] == '/' ? "" : _PATH_DEV, argv[1]); 
	if (disk == NULL)
		errx(1, "Out of memory.");

	fd = open(disk, O_RDONLY);
	if (fd < 0)
		err(1, "Can't open %s", disk);

	if (read(fd, mbr, SEC_SIZE) < 0) 
		err(1, "Can't read %s", disk);
	
	if (!is_valid_br(mbr))
		errx(1, "Invalid MBR on %s.", disk);

	printf("%-9s %10s %10s  %-4s  %s\n"
	       , "Disk:Part", "Start(sect)", "Size(KB)", "Flag", "Type");
	printf("%-9s %10s %10s  %-4s  %s\n"
	       , "---------", "-----------", "--------", "----", "----");
	printf("%s:\n", basename(disk));

	for (i = 0; i < NDOSPART; i++) {
		mbr_prt_ent = &mbr[DOSPARTOFF + i * DOSPARTSIZE];

		if (!is_zero_prt(mbr_prt_ent)) 
			printprt(i + 1, mbr_prt_ent);

		if (is_ext_prt(mbr_prt_ent)) {
			/* extended partition */
			ebr_first = ebr_nxt = u32dec(&mbr_prt_ent[PRT_START]);
			lpcnt = NDOSPART + 1;
			do {
				/* read in EBR for logical partition */
				if (pread(fd, ebr, SEC_SIZE
				          ,ebr_nxt * (off_t)SEC_SIZE)  < 0)
					err(1, "Can't read EBR");

				if (!is_valid_br(ebr)) {
					if (lpcnt == NDOSPART + 1)
						break;
					else
						errx(1, "Invalid EBR");
				}
						

				/* first partition entry in EBR */
				ebr_prt_ent = &ebr[DOSPARTOFF];

				u32dec(&ebr_prt_ent[PRT_START]) += ebr_nxt;
				printprt(lpcnt++, ebr_prt_ent);

				/* second partition entry in EBR */
				ebr_prt_ent += DOSPARTSIZE;
				ebr_nxt = ebr_first + u32dec(&ebr_prt_ent[PRT_START]);

			} while (!is_zero_prt(ebr_prt_ent));
		 } 
	}
        free(disk);
	return 0;
}

static int
is_valid_br(const uint8_t *br)
{

	return br[SEC_SIZE - 1] == 0xaa && br[SEC_SIZE - 2] == 0x55;
}

static int
is_ext_prt(const uint8_t *prt)
{

	return prt[PRT_TYPE] == 0x0f || prt[PRT_TYPE] == 0x05;
}

/* check for empty partition */
static int
is_zero_prt(const uint8_t *pr)
{
	uint32_t	*tst = (uint32_t *)pr;
	
	return !(tst[0] | tst[1] | tst[2] | tst[3]);
}

static const char *
get_type(int type)
{
        int			i, npart_types;
        struct part_type	*ptr = part_types;

	npart_types = sizeof(part_types) / sizeof(struct part_type);
        for (i = 0; i < npart_types; i++, ptr++) 
                if (ptr->type == type)
                        return ptr->name;

        return "?";
}

static void 
printprt(int partno, const uint8_t *part)
{

	printf("%sp%-*d %10u %10u  %-4s  (0x%02x) %s\n"
	       ,partno > NDOSPART ? "      " : "    "
	       ,partno > NDOSPART ? 3 : 5
	       ,partno
	       ,u32dec(&part[PRT_START])
	       ,u32dec(&part[PRT_SIZE]) >> 1	/* assuming SEC_SIZE=512 */
	       ,part[PRT_FLAG] == 0x80 ? "boot" : "-"
	       ,part[PRT_TYPE]
	       ,get_type(part[PRT_TYPE]));
	return;
}
Output:
Code:
Disk:Slice Start(sect)  Size(KB)  Flag  Type
---------- ----------  ---------  ----  ----
ad0:
    s1             63   10240240  -     (0x83) Linux native
    s2       20480544    8192016  boot  (0x83) Linux native
    s3       36864576    8192016  -     (0xa5) FreeBSD/NetBSD/386BSD
    s4       53248670   12456833  -     (0x0f) Extended DOS (LBA)
      s5     53248671    1126408  -     (0x82) Linux swap or Solaris x86
      s6     55501551   11330392  -     (0x0b) DOS or Windows 95 with 32 bit FAT
(for some reason? fbsd fdisk doesn't have support for logical partitions.)
AFAIK getting fbsd partition info from an fbsd slice will also require getting down and dirty.

Last edited by ephemera; 1st August 2008 at 12:37 PM.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Buy/Sell/Free Hardware List DrJ Off-Topic 30 21st October 2023 12:59 PM
PHP~MYSQL - Get list of all the fields within a table cksraj Programming 2 22nd April 2009 05:57 AM
List of users connected by sftp. amscotti OpenBSD General 7 1st April 2009 07:26 PM
Command to list all installed ports? windependence FreeBSD Ports and Packages 2 13th May 2008 11:10 AM


All times are GMT. The time now is 06:00 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Content copyright © 2007-2010, the authors
Daemon image copyright ©1988, Marshall Kirk McKusick