'\" t .\" Title: ldmtool .\" Author: Matthew Booth .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 07/12/2024 .\" Manual: User Commands .\" Source: ldmtool .\" Language: English .\" .TH "LDMTOOL" "1" "07/12/2024" "ldmtool" "User Commands" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" ldmtool \- A tool to manage Microsoft Windows dynamic disks .SH "SYNOPSIS" .HP \w'\fBldmtool\fR\ 'u \fBldmtool\fR [options] .HP \w'\fBldmtool\fR\ 'u \fBldmtool\fR [options] scan [\fIdevice\fR...] .HP \w'\fBldmtool\fR\ 'u \fBldmtool\fR [options] show diskgroup {\fIdisk\ group\ GUID\fR} .HP \w'\fBldmtool\fR\ 'u \fBldmtool\fR [options] show {volume | partition | disk} {\fIdisk\ group\ GUID\fR} {\fIobject\ name\fR} .HP \w'\fBldmtool\fR\ 'u \fBldmtool\fR [options] {create | remove} all .HP \w'\fBldmtool\fR\ 'u \fBldmtool\fR [options] {create | remove} volume {\fIdisk\ group\ GUID\fR} {\fIvolume\ name\fR} .SH "OPTIONS" .PP \fB\-d|\-\-device\fR \fIdevice\fR .RS 4 Automatically scan \fIdevice\fR\&. .RE .SH "DESCRIPTION" .PP \fBldmtool\fR is a tool for managing Microsoft Windows dynamic disks, which use Microsoft\*(Aqs LDM metadata\&. It can inspect them, and also create and remove device\-mapper block devices which can be mounted\&. .PP Although a filesystem can be mounted read\-write and its contents modified, \fBldmtool\fR is not able to modify the LDM metadata itself\&. That is, it cannot create, remove or edit dynamic disks\&. .PP It is also not able to mount RAID5 volumes which have a partition missing, although it can mount mirrored volumes with a partition missing\&. However, mounting a volume with a missing partition is not recommended, as ldmtool does not update the LDM metadata in any way\&. This means Windows will have no way to determine that the partitions are not synchronised when it subsequently mounted, which may result in corruption\&. .SH "INVOCATION" .PP \fBldmtool\fR can be invoked either as a shell to run multiple actions, or to run a single action and return\&. If an action is given on the command line it will run in single action mode\&. If no action is given it will launch a shell\&. .SS "Shell mode" .PP When invoked as a shell, \fBldmtool\fR will not scan any block devices by default\&. If any block devices are given on the command line with the \fB\-d\fR option, these will be scanned\&. Otherwise, block devices must be scanned explicitly with the \fBscan\fR action\&. .PP Exit shell mode by sending an EOF, or with the quit or exit actions\&. .SS "Single action mode" .PP When invoked to run a single action all block devices will be scanned by default\&. In this case, if any block devices are specified with the \fB\-d\fR option, only those block devices will be scanned\&. .SH "RESULTS" .PP \fBldmtool\fR returns results as JSON\-formatted data\&. The precise data returned is described in detail below\&. If a command fails it will not return any JSON data, but will instead display an error message\&. In shell mode, failure can be detected by the lack of a JSON\-formatted result\&. In single action mode the caller can additionally check the exit code of the command\&. .SH "ACTIONS" .SS "scan [device...]" .PP Scan all [device]s for LDM metadata\&. .PP Returns a list of all known disk group GUIDs\&. Note that it doesn\*(Aqt just return newly discovered disk groups\&. .SS "show diskgroup {\fIGUID\fR}" .PP Return detailed information about a single disk group\&. .PP \fBReturns:\fR .PP name .RS 4 The human\-readable name of the disk group .RE .PP guid .RS 4 The Windows\-assigned GUID of the disk group .RE .PP volumes .RS 4 A list of the names of all volumes in the disk group .RE .PP disks .RS 4 A list of the name of all disks in the disk group .RE .SS "show volume {\fIdisk\ group\ GUID\fR} {\fIvolume\ name\fR}" .PP Return detailed information about a volume\&. .PP \fBReturns:\fR .PP name .RS 4 The name of the volume .RE .PP guid .RS 4 The Windows\-assigned GUID of the volume .RE .PP type .RS 4 The volume type\&. One of: simple , spanned , striped , mirrored , raid5 .RE .PP size .RS 4 The size of the volume in sectors .RE .PP chunk\-size .RS 4 The chunk size, in sectors, used by striped and raid5 volumes\&. For other volume types it will be 0\&. .RE .PP hint .RS 4 The volume mounting hint\&. This value specifies how Windows expects the volume to be mounted\&. For a volume with an assigned drive letter, it might be \*(AqE:\*(Aq\&. .RE .PP device .RS 4 The host device\-mapper device which was created for this volume if any (e\&.g\&. /dev/mapper/ldm_vol_Machine\-Dg0_Volume1) .RE .PP partitions .RS 4 A list of the names of the partitions which constitute this volume\&. .RE .SS "show partition {\fIdisk\ group\ GUID\fR} {\fIpartition\ name\fR}" .PP Return detailed information about a partition\&. .PP \fBReturns:\fR .PP name .RS 4 The name of the partition .RE .PP start .RS 4 The offset, in sectors, of the start of the partition from the beginning of the disk .RE .PP size .RS 4 The size of the partition in sectors .RE .PP disk .RS 4 The name of the disk the partition is on .RE .SS "show disk {\fIdisk\ group\ GUID\fR} {\fIdisk\ name\fR}" .PP Return detailed information about a disk\&. .PP \fBReturns:\fR .PP name .RS 4 The human\-readable name of the disk .RE .PP guid .RS 4 The GUID of the disk .RE .PP present .RS 4 Whether the disk has been discovered during scanning: true or false .RE .PP \fBIf the disk is present, additionally returns:\fR .PP device .RS 4 The name of the host device (e\&.g\&. /dev/sda) .RE .PP data\-start .RS 4 The start sector of the data portion of the disk .RE .PP data\-size .RS 4 The size, in sectors, of the data portion of the disk .RE .PP metadata\-start .RS 4 The start sector of the metadata portion of the disk .RE .PP metadata\-size .RS 4 The size, in sectors, of the metadata portion of the disk .RE .SS "create {volume\ {\ \fIdisk\ group\ GUID\fR\ }\ {\ \fIvolume\ name\fR\ } | all}" .PP Create a device\-mapper device for either the specified volume or all volumes in all detected disk groups\&. .PP Returns a list of the device\-mapper device names which were created by this action\&. Note that if a device already existed for a volume it will not be returned in this list\&. .SS "remove {volume\ {\ \fIdisk\ group\ GUID\fR\ }\ {\ \fIvolume\ name\fR\ } | all}" .PP Remove device\-mapper devices for either the specified volume or all volumes in all detected disk groups\&. .PP Returns a list of the device\-mapper device names which were removed by this action\&. Note that if no device existed for a volume it will not be returned in this list\&. .SH "EXAMPLES" .PP The following examples form a sequence from a single session of ldmtool running in shell mode\&. .PP Scan all loop devices for LDM metadata: .sp .if n \{\ .RS 4 .\} .nf ldm> scan /dev/loop[0\-9]* [ "03c0c4fc\-8b6f\-402b\-9431\-4be2e5823b1c", "06495a84\-fbfd\-11e1\-8cf9\-52540061f5db" ] .fi .if n \{\ .RE .\} .PP Two disk groups were detected\&. The list contains their GUIDs\&. .PP Show detailed information about one of the disk groups: .sp .if n \{\ .RS 4 .\} .nf ldm> show diskgroup 06495a84\-fbfd\-11e1\-8cf9\-52540061f5db { "name" : "WIN\-ERRDJSBDAVF\-Dg0", "guid" : "06495a84\-fbfd\-11e1\-8cf9\-52540061f5db", "volumes" : [ "Volume4", "Volume1", "Volume2", "Volume3", "Volume5" ], "disks" : [ "Disk1", "Disk2", "Disk3", "Disk4", "Disk5", "Disk6", "Disk7", "Disk8", "Disk9" ] } .fi .if n \{\ .RE .\} .PP Show detailed information about one of the volumes in the disk group: .sp .if n \{\ .RS 4 .\} .nf ldm> show volume 06495a84\-fbfd\-11e1\-8cf9\-52540061f5db Volume1 { "name" : "Volume1", "guid" : "c08309e9\-1d30\-43e5\-8dc3\-fcec8be76fcc", "type" : "spanned", "size" : 129024, "chunk\-size" : 0, "hint" : "E:", "device" : "ldm_vol_WIN\-ERRDJSBDAVF\-Dg0_Volume1", "partitions" : [ "Disk1\-01", "Disk2\-01" ] } .fi .if n \{\ .RE .\} .PP Show detailed information about one of the partitions in the volume: .sp .if n \{\ .RS 4 .\} .nf ldm> show partition 06495a84\-fbfd\-11e1\-8cf9\-52540061f5db Disk1\-01 { "name" : "Disk1\-01", "start" : 65, "size" : 96256, "disk" : "Disk1" } .fi .if n \{\ .RE .\} .PP Show detailed information about the disk containing the partition: .sp .if n \{\ .RS 4 .\} .nf ldm> show disk 06495a84\-fbfd\-11e1\-8cf9\-52540061f5db Disk1 { "name" : "Disk1", "guid" : "06495a85\-fbfd\-11e1\-8cf9\-52540061f5db", "present" : true, "device" : "/dev/loop15", "data\-start" : 63, "data\-size" : 100289, "metadata\-start" : 100352, "metadata\-size" : 2048 } .fi .if n \{\ .RE .\} .PP Create a device\-mapper device for a volume: .sp .if n \{\ .RS 4 .\} .nf ldm> create volume 06495a84\-fbfd\-11e1\-8cf9\-52540061f5db Volume1 [ "ldm_vol_WIN\-ERRDJSBDAVF\-Dg0_Volume1" ] .fi .if n \{\ .RE .\} .PP A new device\-mapper device has been created, called ldm_vol_WIN\-ERRDJSBDAVF\-Dg0_Volume1\&. Depending on how udev is configured, it will probably now be available as /dev/mapper/ldm_vol_WIN\-ERRDJSBDAVF\-Dg0_Volume1\&. .PP Note that returned name of the created device\-mapper device is unmangled and thus can contains not\-whitelisted characters\&. User\-space device\-mapper tools (like dmsetup) and libdevmapper library accept unmangled names (if properly configured) but take extra care composing path to a created device yourself\&. Consider using "device" field of the \fBshow volume\fR command output\&. .PP Create device\-mapper devices for all volumes in both disk groups: .sp .if n \{\ .RS 4 .\} .nf ldm> create all [ "ldm_vol_Red\-nzv8x6obywgDg0_Volume2", "ldm_vol_Red\-nzv8x6obywgDg0_Volume1", "ldm_vol_Red\-nzv8x6obywgDg0_Volume4", "ldm_vol_Red\-nzv8x6obywgDg0_Stripe1", "ldm_vol_Red\-nzv8x6obywgDg0_Raid1", "ldm_vol_Red\-nzv8x6obywgDg0_Volume3", "ldm_vol_WIN\-ERRDJSBDAVF\-Dg0_Volume4", "ldm_vol_WIN\-ERRDJSBDAVF\-Dg0_Volume2", "ldm_vol_WIN\-ERRDJSBDAVF\-Dg0_Volume3", "ldm_vol_WIN\-ERRDJSBDAVF\-Dg0_Volume5" ] .fi .if n \{\ .RE .\} .PP Note that ldm_vol_WIN\-ERRDJSBDAVF\-Dg0_Volume1 is not in the list of devices which were created as it already existed\&. .PP Remove the device\-mapper device for a single volume: .sp .if n \{\ .RS 4 .\} .nf ldm> remove volume 06495a84\-fbfd\-11e1\-8cf9\-52540061f5db Volume2 [ "ldm_vol_WIN\-ERRDJSBDAVF\-Dg0_Volume2" ] .fi .if n \{\ .RE .\} .sp .if n \{\ .RS 4 .\} .nf ldm> remove all [ "ldm_vol_Red\-nzv8x6obywgDg0_Volume2", "ldm_vol_Red\-nzv8x6obywgDg0_Volume1", "ldm_vol_Red\-nzv8x6obywgDg0_Volume4", "ldm_vol_Red\-nzv8x6obywgDg0_Stripe1", "ldm_vol_Red\-nzv8x6obywgDg0_Raid1", "ldm_vol_Red\-nzv8x6obywgDg0_Volume3", "ldm_vol_WIN\-ERRDJSBDAVF\-Dg0_Volume4", "ldm_vol_WIN\-ERRDJSBDAVF\-Dg0_Volume1", "ldm_vol_WIN\-ERRDJSBDAVF\-Dg0_Volume3", "ldm_vol_WIN\-ERRDJSBDAVF\-Dg0_Volume5" ] .fi .if n \{\ .RE .\} .PP Note that ldm_vol_WIN\-ERRDJSBDAVF\-Dg0_Volume2 is not in the list of devices which were removed, as it was removed previously\&. .SH "AUTHOR" .PP \fBMatthew Booth\fR <\&mbooth@redhat\&.com\&> .RS 4 .RE