I'm installing a software which requires to write data on a disk (i.e.: /dev/sdb) persistently, unfortunately I only have /dev/sda which isn't suitable - I need a second disk to use.
I'm trying to write an empty image of the desired size and then assign it to loop device as in this link but the solution does not cover how to persist data over reboots and I don't know if it's the best way to go.
edit:
the software I'm using is Ceph and during the creation of OSDs is required to specify a device block (not partition).
There are four entries in /dev/disk which I am interested in.
by-id
by-label
by-path
by-uuid
Which of the entries contain immutable names for physical drives? By immutable, I mean that the name shouldn't change if I
change the usb/pci port used to connect to the drive.
destroy and create partitions (GPT).
move from one computer to another (external hard-drive).
For example, /dev/sda can change to /dev/sdb if a different flash drive is connected. But the UUID stays the same. I don't mind if a partition's path changes (I think the UUID changes if you destroy and then recreate a partition), but the complete physical drive must stay at the same location (/dev/sdX may change, but the UUID doesn't when the usb port is changed).
Please suggest relevant tags.
Edit -
Can you say the same for partlabel and partuuid?
In short: you can use by-label or by-uuid to keep names immutable.
In detail:
Disk names (/dev/sdX) are given by kernel based on controller priority (master/slave) disk attached to. If you are moving disk from one USB port to another, for kernel it is like switching a controller. This is why names are changed from /dev/sda to /dev/sdb.
The directory /dev/disk is related to filesystem located on the disk. Label and uuid are filesystem attributes which are given on filesystem creation and can be changed after.
They are immutable and can survive:
disk migration from one computer to another.
disk migration from one controller to another on same computer.
However by-label and by-uuid will not survive if you destroy the partition, but the same label, uuid names can be given upon filesystem creation. So newly created filesystem will be mounted at same mount point.
I personally prefer to use by-label as it supported by many filesystems, short and descriptive.
More information about persistent block device naming.
I was under the impression that a block device is listed under /dev, so for example /dev/xvdf and that file systems live on a partition which is listed with a number behind the block device the partition is on, like /dev/xvdf1 and that all file systems must live on a partition.
I am running CentOS and as part of a course I have to create file systems, partitions and mount file systems. For this course, I have created a file system on device file /dev/xvdf and I have mounted this file system. In addition to that, I have created a partition on /dev/xvdf with the file name of /dev/xvdf1 and created a file system on this partition as well and mounted this file system. This confuses me and I have some questions:
Am I correct that you do not have to create a partition on a block device, but that you can create a file system on a block device directly without a partition?
If so, why would anyone want to do this?
After creating the file system on /dev/xvdf, I created the /dev/xvdf1 partition using fdisk and I allocated the max blocks to this new partition. However, the file system on /dev/xvdf was not removed and still had a file on it. How is this possible if all the blocks on /dev/xvdf have been allocated to the /dev/xvdf1 partition?
Question #1: you are correct. A file system needs only a contiguous space somewhere. You can also create file system in memory (virtual disk).
Question #2: the possibility of having a partition table is a good thing; but why use it if you don't need to break a disk (or other block device) in several pieces?
About question #3, I think you overlooked something - probably an error raised somewhere and you didn't notice, or some error will raise in future. Even if you have the impression, it can not work; the mounted filesystem thinks to own all the space reserved to it, and similarly fdisk thinks that the blocks it is using "can be used". BTW, what is that "/dev/xvdf"? Is it a real device or whatever?
Right, so I've got a Ramdisk image on a mounted device at, say, /mnt/sda1/Ramdisk.img . I want to copy the raw data directly to a ramdisk device at /dev/ram0, in such a way that there will be no need to use mke2fs: I could mount the image and device and find that both are identical.
Ideally this would use only linux commands.
My ideas so far: Mounting the image on a loopback and using basic IO to put the data from one device into the other. I could probably do this with C.
Also, somehow finding the physical address of the ramdisk device and using linux or C commands to put the file directly into the memory.
Thanks in advance.
P.S: I know that the kernel somehow flags memory which was used for ramdisks so the system does not reclaim it. Anyone know where these flags are?
Any kind of copy command is going to require a partition and filesystem at the destination. However, dd can work at the disk or partition level, by just specifying the disk (eg /dev/sda) or partition (eg (dev/sda1) level. So in theory, you could do
dd if=ramdisk_image_file of=/dev/ram0
I'd like to programmatically make a snapshot of a live filesystem in Linux, preferably using LVM. I'd like not to unmount it because I've got lots of files opened (my most common scenario is that I've got a busy desktop with lots of programs).
I understand that because of kernel buffers and general filesystem activity, data on disk might be in some more-or-less undefined state.
Is there any way to "atomically" unmount an FS, make an LVM snapshot and mount it back? It will be ok if the OS will block all activity for few seconds to do this task. Or maybe some kind of atomic "sync+snapshot"? Kernel call?
I don't know if it is even possible...
You shouldn't have to do anything for most Linux filesystems. It should just work without any effort at all on your part. The snapshot command itself hunts down mounted filesystems using the volume being snapshotted and calls a special hook that checkpoints them in a consistent, mountable state and does the snapshot atomically.
Older versions of LVM came with a set of VFS lock patches that would patch various filesystems so that they could be checkpointed for a snapshot. But with new kernels that should already be built into most Linux filesystems.
This intro on snapshots claims as much.
And a little more research reveals that for kernels in the 2.6 series the ext series of filesystems should all support this. ReiserFS probably also. And if I know the btrfs people, that one probably does as well.
I know that ext3 and ext4 in RedHat Enterprise, Fedora and CentOS automatically checkpoint when a LVM snapshot is created. That means there is never any problem mounting the snapshot because it is always clean.
I believe XFS has the same support. I am not sure about other filesystems.
It depends on the filesystem you are using. With XFS you can use xfs_freeze -f to sync and freeze the FS, and xfs_freeze -u to activate it again, so you can create your snapshot from the frozen volume, which should be a save state.
Is there any way to "atomically" unmount an FS, make an LVM snapshot and mount it back?
It is possible to snapshot a mounted filesystem, even when the filesystem is not on an LVM volume. If the filesystem is on LVM, or it has built-in snapshot facilities (e.g. btrfs or ZFS), then use those instead.
The below instructions are fairly low-level, but they can be useful if you want the ability to snapshot a filesystem that is not on an LVM volume, and can't move it to a new LVM volume. Still, they're not for the faint-hearted: if you make a mistake, you may corrupt your filesystem. Make sure to consult the official documentation and dmsetup man page, triple-check the commands you're running, and have backups!
The Linux kernel has an awesome facility called the Device Mapper, which can do nice things such as create block devices that are "views" of other block devices, and of course snapshots. It is also what LVM uses under the hood to do the heavy lifting.
In the below examples I'll assume you want to snapshot /home, which is an ext4 filesystem located on /dev/sda2.
First, find the name of the device mapper device that the partition is mounted on:
# mount | grep home
/dev/mapper/home on /home type ext4 (rw,relatime,data=ordered)
Here, the device mapper device name is home. If the path to the block device does not start with /dev/mapper/, then you will need to create a device mapper device, and remount the filesystem to use that device instead of the HDD partition. You'll only need to do this once.
# dmsetup create home --table "0 $(blockdev --getsz /dev/sda2) linear /dev/sda2 0"
# umount /home
# mount -t ext4 /dev/mapper/home /home
Next, get the block device's device mapper table:
# dmsetup table home
home: 0 3864024960 linear 9:2 0
Your numbers will probably be different. The device target should be linear; if yours isn't, you may need to take special considerations. If the last number (start offset) is not 0, you will need to create an intermediate block device (with the same table as the current one) and use that as the base instead of /dev/sda2.
In the above example, home is using a single-entry table with the linear target. You will need to replace this table with a new one, which uses the snapshot target.
Device mapper provides three targets for snapshotting:
The snapshot target, which saves writes to the specified COW device. (Note that even though it's called a snapshot, the terminology is misleading, as the snapshot will be writable, but the underlying device will remain unchanged.)
The snapshot-origin target, which sends writes to the underlying device, but also sends the old data that the writes overwrote to the specified COW device.
Typically, you would make home a snapshot-origin target, then create some snapshot targets on top of it. This is what LVM does. However, a simpler method would be to simply create a snapshot target directly, which is what I'll show below.
Regardless of the method you choose, you must not write to the underlying device (/dev/sda2), or the snapshots will see a corrupted view of the filesystem. So, as a precaution, you should mark the underlying block device as read-only:
# blockdev --setro /dev/sda2
This won't affect device-mapper devices backed by it, so if you've already re-mounted /home on /dev/mapper/home, it should not have a noticeable effect.
Next, you will need to prepare the COW device, which will store changes since the snapshot was made. This has to be a block device, but can be backed by a sparse file. If you want to use a sparse file of e.g. 32GB:
# dd if=/dev/zero bs=1M count=0 seek=32768 of=/home_cow
# losetup --find --show /home_cow
/dev/loop0
Obviously, the sparse file shouldn't be on the filesystem you're snapshotting :)
Now you can reload the device's table and turn it into a snapshot device:
# dmsetup suspend home && \
dmsetup reload home --table \
"0 $(blockdev --getsz /dev/sda2) snapshot /dev/sda2 /dev/loop0 PO 8" && \
dmsetup resume home
If that succeeds, new writes to /home should now be recorded in the /home_cow file, instead of being written to /dev/sda2. Make sure to monitor the size of the COW file, as well as the free space on the filesystem it's on, to avoid running out of COW space.
Once you no longer need the snapshot, you can merge it (to permanently commit the changes in the COW file to the underlying device), or discard it.
To merge it:
replace the table with a snapshot-merge target instead of a snapshot target:
# dmsetup suspend home && \
dmsetup reload home --table \
"0 $(blockdev --getsz /dev/sda2) snapshot-merge /dev/sda2 /dev/loop0 P 8" && \
dmsetup resume home
Next, monitor the status of the merge until all non-metadata blocks are merged:
# watch dmsetup status home
...
0 3864024960 snapshot-merge 281688/2097152 1104
Note the 3 numbers at the end (X/Y Z). The merge is complete when X = Z.
Next, replace the table with a linear target again:
# dmsetup suspend home && \
dmsetup reload home --table \
"0 $(blockdev --getsz /dev/sda2) linear /dev/sda2 0" && \
dmsetup resume home
Now you can dismantle the loop device:
# losetup -d /dev/loop0
Finally, you can delete the COW file.
# rm /home_cow
To discard the snapshot, unmount /home, follow steps 3-5 above, and remount /home. Although Device Mapper will allow you to do this without unmounting /home, it doesn't make sense (since the running programs' state in memory won't correspond to the filesystem state any more), and it will likely corrupt your filesystem.
I'm not sure if this will do the trick for you, but you can remount a file system as read-only. mount -o remount,ro /lvm (or something similar) will do the trick. After you are done your snapshot, you can remount read-write using mount -o remount,rw /lvm.
FS corruption is "highly unlikely", as long as you never work in any kind of professional environment. otherwise you'll meet reality, and you might try blaming "bit rot" or "hardware" or whatever, but it all comes down to having been irresponsible. freeze/thaw (as mentioned a few times, and only if called properly) is sufficient outside of database environments. for databases, you still won't have a transaction-complete backup and if you think a backup that rolls back some transaction is fine when restored: see starting sentence.
depending on the activity you might just added another 5-10 mins of downtime if ever you need that backup.
Most of us can easily afford that, but it can not be general advice.
Be honest about downsides, guys.