Partimage-manual Partition Image Internals

From Partimage
Jump to: navigation, search

Note about the NTFS support

Note for users

The NTFS file system is very complex (system files are implemented as regular files). For this reason it is not fully supported in Partition Image. It mean that you can have problems when trying to save an NTFS partition, if your system files are very fragmented, or are not written in standards location. Then, you will have a warning at the beginning of the operation: The NTFS support is experimental.

But in most cases, it will work without any problem. The best thing to do is to try to save your NTFS partition. If you have an error message, then you will have to stop. If there was no error, you can continue. If you can save the partition, you won't have problem when trying to restore (except if there is a bug).

Details for developers

The only difficulty we have with adding NTFS support to Parititon Image is that the $Bitmap system file is difficult to read. In deed, all system files as the $MFT, $Bitmap, ... are written on the disk as regulars files. Then, to read the bitmap, all the code need to read files need to be implemented.

$Bitmap is a file that contains a map of bits. Each cluster of the NTFS partition can be used or free. There is a bit in the bitmap for each cluster. The bit is 0 if the cluster is free and is 1 if the cluster is used.

Partition Image need to read the bitmap to know what clusters are used. Then, it is possible to copy only used clusters of the partition.

With the boot sector, we can read the FILE RECORD of the $MFT. We must then read the FILE RECORD of the $Bitmap file. But now, we only read this record at a constant position, which may be false if the MFT was fragmented.

1) First problem: how to have the position of the File Record of the $Bitmap file ?

Then, if we have this file record, we can check the file name, and read the run list, to know what clusters contains the bitmap data. But we have another problem: If the $bitmap is very fragmented, the run list cannot be written in the base file record. Then we must use the "attribute list" to have another run lists...

2) Second problem: how to read the "attribute list" to be able to read all clusters which contains the $bitmap data...

Without the $Bitmap file, we must save all clusters, even the free ones... That's not a good way.

3) Another problem is the compression: what to do if the $bitmap file is compressed ?

The 2 GB file limitation

The linux 2.2 kernel does not support files larger than 2 GB, so the size of your image must not exceed this limit. You can solve this problem using the 2.4 kernel, which doesn't have this limitation. You can also split your image into small files (of 1,9 GB for example). You also require a recent glibc version: 2.2 or newer.

How are the partitions read/written

Partition Image use a low level implementation. It mean that Partition Image makes a block/cluster copy, when saving/restoring data. It read and write physical blocks of the partition. It doesn't use the linux kernel (file systems support) to read data. It has many advantages:

Dumping is fast, because there is no need to seek between indexes (FAT, inode table, ...) and files contents. No seek between blocks when a file is fragmented. It really copies all the data of the file system: files contents, boot sector, inodes, ... Absolutely no modification can be made while saving/restoring It keeps the file locations. For example, the location of your kernel image will be kept, and LILO won't fail after you restore your partition.

But with this method, all files systems support must be implemented, and it's difficult to resize the partition when restoring. It is also impossible to extract a file from an image.

Developers information

64 bits numbers

Many numbers are written in 64 bits, for example file sizes, in order to avoid future limitations of the file formats. 64 bits variables must be declared as QWORD, this is defined as unsigned long long int in partimage.h

reserved data for future use

There is free space, reserved for future use, in the main header, and in each file header, in order to add other informations in the future, without making archives files uncompatibles.

variables names

Variables names are written in the following format: PositionTypeName:

  • Position: g_ for global variables, m_ for class members, and nothing for local variables.
  • Type: b for bool, n for int, qw for QWORD, sz for a NULL terminated string in ASCII, c for a char, f for a FILE* stream, dw for DWORD, ...
  • Name: the name of the variable, with an uppercase letter at the beginning of each word


  • m_bArchiveOpened: member of KFileCoderDoc (m_), of bool type (b), name = "ArchiveOpened"
  • dwLength: local, of DWORD type (dw), name = "Length"
  • g_szArchivePath: global variable (g_), null terminated ASCII string (sz), name = "ArchivePath"

This has a lot of advantages: When you see a variable, you know the type (int, bool, FILE *), and you know if it's a global, local or member one.

Likewise, if two variables have the same name, if resolves the problem. For example, we have:

bool CImage::m_qwCRC;

QWORD CImage::get_qwCRC()
  return m_qwCRC;

void CImage::setState(bool bState)
        m_bState = bState;

instead of:

bool CImage::CRC;

void CImage::setState(bool state2)
        state = state2;