Search code examples
linuxwindowsservermigrationperforce

Perforce: Cross-Migration from Windows to Linux fails to replay checkpoint


I am attempting to migrate my personal Perforce Server from Windows to Linux (Ubuntu 20.04), but am having trouble replaying the checkpoint file from the Windows Server on the Linux Server.

I want to inherit Linux's case-handling, which according to Perforces' documentation should be possible using the p4migrate tool. I've installed the tool on the Linux Server and followed the documentation steps to the letter (several times at this point), but still keep running into the following error.

Note that when using p4migrate to create the edited checkpoint file, it reported that there were no reported case issues/conflicts. On the first attempt, it also successfully renamed all the archive files to match Linux's case handling (and I have already changed the line-endings).

It's just the database that it can't seem to restore. I'm using the following command to rebuild the database from the checkpoint file that p4migrate creates:

p4d -r /mnt/Disk/PerforceServer/root -jr checkpoint.4.edited

But doing so yields the following output:

Perforce db files in '/mnt/Disk/PerforceServer/root' will be created if missing...
Recovering from checkpoint.4.edited...
Perforce server error:
    Journal file 'checkpoint.4.edited' replay failed at line 5145!
    Case-handling mismatch: server uses Unix-style (-C0) but journal flags are Windows-style (-C1)!

I've made a few attempts but the result is always the same. It creates all the .db files, but then stops almost instantly. I have naturally checked the line(s) it reported and been over the checkpoint file (some 45mb) with a fine toothcomb, but found no issues.

I suspect something else is at play here but there doesn't appear to be a way to get more verbose logging. Has anybody run into this before and found the solution?

Addendum: I have also run p4d -jv checkpoint.4.edited which only reported the following: trailer found on line 196624 (the end of the file)


Solution

  • After a week of hair-loss inducing experiences, I was at last able to get the information I needed to resolve the issue. The first point of note is that the error given above is completely misleading. There is in fact no issue with the checkpoint file at the line it mentions, it's purely an issue of case-handling. I have no idea why it spits out that line as the error, but it's nothing to do with it.

    As a reminder, I am transferring a Windows server to Linux one (Ubuntu 20.04), and I'm using Perforce version 20.3. You MUST ensure both versions on the source and target machine are the same. I solved this by updating my windows Server, then running the p4d -xU command to upgrade the database.

    My aim was also to run a case-sensitive server on Linux. Perforce provides the p4migrate tool to support this transition, but at least in my experience so far, the tool has a couple of bugs and the documentation contains an error or two. I'll forward my findings to P4 in the hope they fix it, unless I was just very unlucky of course.

    The Solution:

    You will want to follow all of the steps found in the p4migrate documentation UP TO AND INCLUDING Step 4. Step 5 is where things start to differ. The issue is that p4migrate does not seem to actually change the case-handling method in the checkpoint file, so you have to manually set it. I'm not sure if this is a bug, but this solves the case mismatch/BTree issue and replays the checkpoint successfully.

    The case-handling method can be manually alterned by adjusting the first @nx@ entry (the first line of the checkpoint file for me). The fifth field denotes it. 1 = Case-Sensitive, 2 = Case-Insensitive. To change a checkpoint to case-sensitive, do the following:

        @nx@ 0 1610070027 @51@ 2 0 0 0 0 @/path/to/root@ @journal@ @@ @@ @@
    
    Changes to:
    
        @nx@ 0 1610070027 @51@ 1 0 0 0 0 @/path/to/root@ @journal@ @@ @@ @@
    

    As a point of note, I did this with both the input AND output file from p4migrate. Even after editing the input checkpoint, p4migrate still outputted a case-insensitive checkpoint (perhaps this is because I had no conflicts to resolve). Once you've done this, continue with the remaining steps up to and including Step 10. The command I used to replay the checkpoint at this step is as follows:

    p4d -r /Folder1/Folder2/PerforceServer/root/ -jr checkpoint.n.edited
    

    You can then start a case-sensitive Server. Note that every file I ran p4 verify -q //... against returned the BAD! warning at this stage, but I had no MISSING! warnings. As the documentation says, you can ignore the BAD! warnings at the moment.

    Finally, there seems to be TWO versions of the command shown in Step 11. The one from the p4migrate documentation.

    find $P4ROOT -type f \( -name "*,v" -o -name ".*,v" \) -print \
        -exec perl -p -i -e 's/\r\n/\n/' \{} \;
    

    And the one from the Cross-Platform Migration knowledgebase article.

    find . -type f -name '*,v' -print -exec perl -p -i -e 's/\r\n/\n/g' {} \;
    

    Notice the subtle difference. I'm not a Linux/Perl expert - but the missing 'g' in the p4migrate documentation suggests to me there's a typo there. As a result, I ran this version of the command for each depot, just to be explicit:

    find /folder/anotherfolder/Depot1/ -type f -name '*,v' -print -exec perl -p -i -e 's/\r\n/\n/g' {} \;
    find /folder/anotherfolder/Depot2/ -type f -name '*,v' -print -exec perl -p -i -e 's/\r\n/\n/g' {} \;
    

    etc...

    I then ran p4 verify -q //... once again (Step 12), and it returned no errors! Now all you need to do is start a case-sensitive Perforce service with p4dctl and you're away. Syncing works again, and I didn't even have to manually force p4 verify to update the MD5 checksums. Hopefully this helps anyone else who stumbles on this issue.