PVCREATE(8)

πŸ’– PVCREATE(8) β€” the manual page, but make it make sense πŸ’–

okay so bestie. you found pvcreate, section 8 of the System Manager's Manual, and honestly? iconic of you. this is the one that initialize physical volume(s) for use by LVM. that's the whole ~name~ of the game. let's go. πŸ¦‹


✨ SYNOPSIS ✨

pvcreate position_args
       [ option_args ]

like, that's it. that's the shape of it. give it a position arg, sprinkle some options on top. chef's kiss. πŸ’…


🌸 DESCRIPTION 🌸

so pvcreate initializes a Physical Volume (PV) on a device so that the device is recognized as belonging to LVM. that's the entire personality of this command. once it does that, the PV can be used in a Volume Group (VG). it does this by writing an LVM disk label to the device and initializing the LVM metadata areas. no cap. πŸ’«

and fr fr, a PV can live on a whole device or on a partition. both are valid, both are welcome here. 🫢

now, what do you do after? use vgcreate(8) to create a brand new VG on the PV, or vgextend(8) to add the PV to a VG you already have. and if you ever want to break up with LVM and get your device back, pvremove(8) removes the LVM disk label from the device. it's giving closure. 😌


πŸ”₯ the force thing (listen up) πŸ”₯

the force option will create a PV without confirmation. so it just kinda does it. and if you repeat the force option β€” that's -ff β€” it will forcibly create a PV, overriding checks that normally prevent it, e.g. if the PV is already in a VG. that's the "i know what i'm doing" button. respect it. fear it a little. 😭


πŸ“ Metadata location, size, and alignment πŸ“

okay this is the meaty part, stay with me, it's actually so interesting i promise. ✨

  • the LVM disk label begins 512 bytes from the start of the device, and is 512 bytes in size. tiny. precious. a little baby label. πŸŽ€
  • the LVM metadata area begins at an offset (from the start of the device) equal to the page size of the machine creating the PV β€” often 4 KiB. the metadata area contains a 512 byte header and a multi-KiB circular buffer that holds text copies of the VG metadata. so it's like a lil notebook that keeps rewriting itself. obsessed. πŸ““
  • with default settings, the first physical extent (PE) β€” which is the thing that contains LV data β€” is 1 MiB from the start of the device. this location is controlled by default_data_alignment in lvm.conf, which is set to 1 (MiB) by default. the pe_start will be a multiple of this many MiB. you can check this location with:
pvs -o pe_start PV
  • the size of the LVM metadata area is the space between the start of the metadata area and the first PE. so when metadata begins at 4 KiB and the first PE is at 1024 KiB, the metadata area size is 1020 KiB. check it with:
pvs -o mda_size PV
🚨 IMPORTANT: the mda_size cannot be increased after pvcreate. so if you need bigger metadata, it has to be set during pvcreate. no takebacks, bestie.

two copies of the VG metadata must always fit within the metadata area, so the maximum VG metadata size is around half the mda_size. check that one with:

vgs -o mda_free VG

a larger metadata area can be set with --metadatasize. but heads up β€” the resulting mda_size may be larger than you specified, because of default_data_alignment placing pe_start on a MiB boundary, plus the fact that the metadata area extends to the first PE. it's giving "you asked for a small thing and got a slightly bigger thing." πŸ™ˆ

okay concrete numbers so it's real:

  • with metadata starting at 4 KiB and default_data_alignment 1 (MiB), setting --metadatasize 2048k results in pe_start of 3 MiB and mda_size of 3068 KiB.
  • alternatively, --metadatasize 2044k results in pe_start at 2 MiB and mda_size of 2044 KiB.

see? math girlies stay winning. πŸ‘‘


🌈 the automatic override thing 🌈

the alignment of pe_start described above may be automatically overridden based on md device properties or device I/O properties reported in sysfs. these automatic adjustments can be enabled/disabled using the lvm.conf settings md_chunk_alignment and data_alignment_offset_detection. the machine said "i'll handle it" and sometimes it does. πŸ€–


πŸ’… when you want a different alignment πŸ’…

to use a different pe_start alignment, use the --dataalignment option. the --metadatasize option would also typically be used in this case, because the metadata area size also determines the location of pe_start. they're besties, they come as a pair. πŸ«‚

when using these two options together, pe_start is calculated as: metadata area start (page size), plus the specified --metadatasize, rounded up to the next multiple of --dataalignment. that's the formula, that's the whole thing.

so with metadata starting at 4 KiB, --metadatasize 2048k, and --dataalignment 128k, pe_start is 2176 KiB and mda_size is 2172 KiB. the pe_start of 2176 KiB is the nearest exact multiple of 128 KiB that provides at least 2048 KiB of metadata space. slay.

⚠️ always check the resulting alignment and metadata size when using these options. do not just vibes-based configure your storage. πŸ’€

🎯 shifting the alignment 🎯

to shift an aligned pe_start value, use the --dataalignmentoffset option. the pe_start alignment is calculated as described above, and then the value specified with --dataalignmentoffset is added to produce the final pe_start value. it's the little nudge. the afterthought. the trailing sparkle. ✨


πŸ›  USAGE πŸ› 

here's the whole vibe in one block:

pvcreate PV ...
       [ -f|--force ... ]
       [ -M|--metadatatype lvm2 ]
       [ -u|--uuid String ]
       [ -Z|--zero y|n ]
       [ --bootloaderareasize Size[m|UNIT] ]
       [ --dataalignment Size[k|UNIT] ]
       [ --dataalignmentoffset Size[k|UNIT] ]
       [ --labelsector Number ]
       [ --metadataignore y|n ]
       [ --metadatasize Size[m|UNIT] ]
       [ --norestorefile ]
       [ --[pv]metadatacopies 0|1|2 ]
       [ --reportformat basic|json|json_std ]
       [ --restorefile String ]
       [ --setphysicalvolumesize Size[m|UNIT] ]
       [ COMMON_OPTIONS ]

and the common options for lvm, which basically every lvm command shares because why would they make you learn a new one:

[ -d|--debug ... ]
[ -h|--help ]
[ -q|--quiet ... ]
[ -t|--test ]
[ -v|--verbose ... ]
[ -y|--yes ]
[ --commandprofile String ]
[ --config String ]
[ --devices PV ]
[ --devicesfile String ]
[ --driverloaded y|n ]
[ --journal String ]
[ --lockopt String ]
[ --longhelp ]
[ --nohints ]
[ --nolocking ]
[ --profile String ]
[ --version ]

okay we're not done yet bestie, there's more coming β€” stay tuned for part 2 πŸ’–

Undocumented and severe, bestie β€” this is the big wall of flags. Bestie, there's like forty of them, and I am not skipping a single one. Grab a snack. πŸ“

  • --bootloaderareasize Size[m|UNIT] β€” Reserves a lil pocket of space for the bootloader, sitting right between the LVM metadata area and the first PE. It's for bootloaders to embed their own data/metadata in; LVM will not touch it. The bootloader area starts exactly where the first PE would've gone otherwise. The first PE gets pushed out by the size of the bootloader area, and pushed out even further if that's needed to match the data alignment. The start of the bootloader area is always aligned β€” peep --dataalignment and --dataalignmentoffset. The area might end up bigger than you asked for because of alignment, but it's never smaller. To see the bootloader area start and size of an existing PV, run pvs -o +pv_ba_start,pv_ba_size.
  • --commandprofile String β€” The command profile used for command config. lvm.conf(5) has the whole story on profiles.
  • --config String β€” Config settings for the command. These override the lvm.conf(5) settings. The String arg uses the same format as lvm.conf(5), or you can use section/field syntax. Again, lvm.conf(5) for the deets.
  • --dataalignment Size[k|UNIT] β€” Lines up the start of a PV data area to a multiple of this number. Wanna see where the first Physical Extent (PE) of an existing PV is? pvs -o +pe_start. It can also get shifted by an alignment offset, see --dataalignmentoffset. Oh, and set an appropriate PE size when you make a VG, bestie. ✨
  • --dataalignmentoffset Size[k|UNIT] β€” Shifts the start of the PV data area by this extra offset.
  • -d, --debug ... β€” Sets debug level. Repeat 1 to 6 times to crank up how much detail goes to the log file and/or syslog (if it's configured).
  • --devices PV β€” Restricts which devices are visible and accessible to the command. Devices not on the list will look like they're missing. This option can be repeated, or it takes a comma-separated list of devices. This overrides the devices file.
  • --devicesfile String β€” A file listing the devices LVM should use. It has to exist in /etc/lvm/devices/ and it's managed with the lvmdevices(8) command. This overrides the lvm.conf(5) devices/devicesfile and devices/use_devicesfile settings.
  • --driverloaded y|n β€” Set it to no and the command won't even try to use device-mapper. For testing and debugging.
  • -f, --force ... β€” Overrides assorted checks, confirmations and protections. ⚠️ Use with extreme caution, bestie, I'm so serious.
  • -h, --help β€” Displays help text.
  • --journal String β€” Records info in the systemd journal. This is on top of whatever info the lvm.conf log/journal setting already enables. command: record info about the command. output: record the default command output. debug: record full command debugging.
  • --labelsector Number β€” By default the PV gets labelled with an LVM2 identifier in its second sector (sector 1). This lets you use a different sector near the start of the disk (between 0 and 3 inclusive β€” see LABEL_SCAN_SECTORS in the source). Use with care.
  • --lockopt String β€” Used to pass options for special cases over to lvmlockd. See lvmlockd(8) for more.
  • --longhelp β€” Displays long help text.
  • --metadataignore y|n β€” Sets the metadataignore property of a PV. If yes, metadata areas on the PV are ignored and lvm won't store metadata in the PV's metadata areas. If no, lvm will store metadata on the PV.
  • --metadatasize Size[m|UNIT] β€” The approximate amount of space used for each VG metadata area. The size may get rounded.
  • -M, --metadatatype lvm2 β€” Sets the type of on-disk metadata to use. lvm2 (or just 2) is the current, standard format. lvm1 (or just 1) is no longer used β€” rip, it's giving vintage πŸ’€.
  • --nohints β€” Don't use the hints file to locate devices for PVs. Without hints, a command might read more devices to find PVs. It'll still do the standard hint file invalidation where appropriate, no cap.
  • --nolocking β€” Disables locking. Use with caution β€” concurrent commands can produce incorrect results. 😬
  • --norestorefile β€” Teams up with --uuid to let you specify a UUID without also needing a backup of the metadata to be provided.
  • --profile String β€” An alias for --commandprofile or --metadataprofile, depending on the command.
  • --[pv]metadatacopies 0|1|2 β€” How many metadata areas to set aside on a PV for storing VG metadata. When 2, one copy of the VG metadata goes at the front of the PV and a second copy goes at the end. When 1, one copy goes at the front of the PV. When 0, no copies of the VG metadata get stored on that PV. Handy in VGs with tons of PVs (tho heads up: this places limitations on using vgsplit later).
  • -q, --quiet ... β€” Suppresses output and log messages. Overrides --debug and --verbose. Repeat it once and it also suppresses any prompts with the answer 'no'.
  • --reportformat basic|json|json_std β€” Overrides the current output format for reports, which is set globally by the report/output_format setting in lvm.conf(5). basic is the original format with columns and rows. If a command has more than one report, each report gets prefixed with the report name so you can tell them apart. json produces report output in JSON. json_std also gives you JSON but more compliant with the JSON standard. See lvmreport(7) for more.
  • --restorefile String β€” With --uuid, this reads the file (produced by vgcfgbackup), pulls out the location and size of the data on the PV, and makes sure the metadata the program produces is consistent with the file's contents β€” i.e. the physical extents end up in the same place and don't get overwritten by new metadata. This gives you a way to upgrade the metadata format or add/remove metadata areas. Use with care.
  • --setphysicalvolumesize Size[m|UNIT] β€” Overrides the automatically detected size of the PV. Use with care, or before you reduce the physical size of the device.
  • -t, --test β€” Runs in test mode. Commands won't update metadata. It works by disabling all metadata writing but still returning success to the calling function anyway. Fair warning: this can produce unusual error messages in multi-stage operations if a tool relies on reading back metadata it thinks changed but didn't. πŸ™ˆ
  • -u, --uuid String β€” Specify a UUID for the device. Without this, a random UUID gets generated. You need this before restoring a backup of LVM metadata onto a replacement device β€” see vgcfgrestore(8). Because of that, --restorefile is compulsory unless --norestorefile is used. Every PV has to have a unique UUID, and LVM will block certain operations if it sees multiple devices with the same UUID. See vgimportclone(8) for more.
  • -v, --verbose ... β€” Sets verbose level. Repeat 1 to 4 times to increase the detail of messages sent to stdout and stderr.
  • --version β€” Displays version information.
  • -y, --yes β€” Don't prompt for confirmation interactively, just always assume the answer is yes. πŸ’… Use with extreme caution. (For automatic no, see -qq.)
  • -Z, --zero y|n β€” Controls whether the first 4 sectors (2048 bytes) of the device get wiped. The default is to wipe these sectors unless either or both of --restorefile or --uuid are specified.

🌈 VARIABLES 🌈

  • PV β€” Physical Volume name, a device path under /dev. For commands that manage physical extents, a PV positional arg generally accepts a suffix indicating a range (or multiple ranges) of physical extents (PEs). When the first PE is omitted, it defaults to the start of the device; when the last PE is omitted, it defaults to the end.

Start and end range (inclusive): PV[:PE-PE] ...

Start and length range (counting from 0): PV[:PE+PE] ...

  • String β€” See the option description for info about the string content.
  • Size[UNIT] β€” Size is an input number that accepts an optional unit. Input units are always treated as base two values, no matter the capitalization β€” e.g. k and K both mean 1024. The default input unit is specified by the letter, followed by |UNIT. UNIT represents the other possible input units: b|B is bytes, s|S is sectors of 512 bytes, k|K is KiB, m|M is MiB, g|G is GiB, t|T is TiB, p|P is PiB, e|E is EiB. (Don't confuse this with the output control --units, where capital letters mean a multiple of 1000!) πŸ‘‘

🌸 ENVIRONMENT VARIABLES 🌸

See lvm(8) for info about environment variables used by lvm. For example, LVM_VG_NAME can generally be substituted for a required VG parameter.


✨ EXAMPLES ✨

Initialize a partition and a full device.

pvcreate /dev/sdc4 /dev/sde

If a device is a 4 KiB sector drive that compensates for Windows partitioning (sector 7 is the lowest aligned logical block, the 4 KiB sectors start at LBA -1, and consequently sector 63 is aligned on a 4 KiB boundary), manually account for this when initializing for use by LVM.

pvcreate --dataalignmentoffset 7s /dev/sdb

πŸ”— SEE ALSO ✨ (aka the whole friend group πŸ’–)

ngl bestie, pvcreate does not work alone. it's giving main character but it's got a whole ensemble cast, and every single one of them has a man page you can go read. go say hi πŸ‘‹


fr fr, if you're confused about anything you just read, the answer is in one of these. the man pages are the group chat archive. iykyk πŸ’€

that's a wrap on PVCREATE(8), bestie πŸ’– this whole thing is brought to you by Red Hat, Inc., it's LVM TOOLS 2.03.44(2), dated 2026-10-27, and it lives at the very bottom of the PVCREATE(8) page. now go make some physical volumes, you absolute icon πŸ‘‘βœ¨

πŸ“¦ where this page comes from