See also my followup post.
One of the computers I have at home is designated as a 'Library computer'. I wanted to be sure that the data that is put in there would survive a hard drive failure, so I was using a RAID-5 array with four 320GB hard drives, totaling in about 960GB or 894GiB (gibibytes). All but two of the hard drives were different models.
About a month ago, the nForce chipset started to show red message on bootup screen saying that the array is in "Degraded" mode, as one of the drives had failed a SMART test and was rejected. I sent the drive to be switched under RMA and got now a new one. The manufacturer of the new drive was the same (Samsung), but the model was different. The old drive was a Spinpoint F1, the new drive is Spinpoint T166. Otherwise the units seemed to be identical -- both had 320GB capacity, 7200rpm, 16MiB cache and SATA-II interface.
I plugged the drive in and booted the computer up, only to find that the array was still in Degraded mode and the new drive was also rejected. I rebooted into RAID BIOS and tried to manually engage the Rebuild option, but that failed complaining that the new drive was too small?
After inspecting the actual size of the drives, things started to clear up. While all of the drives were noted to be 320GB (or 298.02GiB in binary system), the actual capacity of the drives varied between different manufacturers and even between different models of the same manufacturer. The RAID uses the actual size of the smallest drive in an array. In my case, the original array used 298.09GiB as that size. The new drive however registered 298.08GiB as its actual size - this is 0.01GiB, or about 10 megabytes smaller. As such it was not possible to use this drive.
The lesson here is simple -- never allow the maximum size of the currently smallest drive to be the size that is used to make up the array. Take a good 0.1GiB off of it. You'll only lose a few hundred megabytes, but when it's time to swap out a failed drive, the capacity of the new drive might be less than what the old one had and you'll end up coping the whole array to a separate large hard drive and redo the whole setup (just as I had to do).
Trying to spread knowledge about IT technology, Linux, programming (Java and Adobe Flex) and similar topics.
Wednesday, December 31, 2008
Tuesday, December 2, 2008
How to release software...
Today, in our team, we had an argument about how to manage the software quality.
I've previously worked for another organization where the releasing was done very differently. In there, the software was released file-by-file as opposed to by package. When you needed to make some changes to already existing piece of software, you checked out the relevant file(s), modified it (them) and committed the change(s) back, noting what revision did the new file(s) get. After that you created a change document and filled it with the name(s) of the file(s) which were changed, the new revision and the reason for the change. The software releasing team got the change document, checked out the necessary revisions you had written in the document, compiled them and released them.
In my current organization, the releasing is done monthly (sometimes even less frequently) in one big package. In addition to that, our Flex application is submitted also as a package, which we compile ourselves (the resulting SWF is released).
The problem we are facing has to do with release quality. Since the software is released as a package, it becomes vitally important to track which changes to the individual Flex source files get to go into the package and which must be left out, since they are not yet complete. Still, in development environment we need the latest state there is (so called nightly build). The question is - how to track the changes? How to differentiate the changes of the future from the immediate changes scheduled to be released next?
Normally, the development environment is compiled from the HEAD of the CVS - with all the latest changes. Up until recently the same HEAD build was also released. Since we now are doing more and more future developments that do not need to get in anytime soon, that started to create problems for us. For example, in order to demonstrate my new development, I had to commit the changes, so that the nightly build process would build it into the development environment. But this can no longer be the version that goes out as a release version, since my new development should not be released yet... How to solve this?
Some parts of our organization are using extensive branching. Any bugfixing to production code is performed on a branch which is later merged with the HEAD code... this is a very difficult process with lots of errors which we hoped to avoid.
My suggestion was to use a special tag to track the revisions of the source files which are used to compile the release SWF. The tag name might be anything, for example "GO". This tag is given to all the files that are scheduled to go out next - the release build process will only check out files with the "GO" tag (as opposed to the nightly build process, which checks out HEAD).
If there are any future changes which should not go into the next release, then those files are not to be tagged with the "GO" tag, so that tag will remain on the older revision of these files. Hence the release build process will ignore the future changes, while the nightly build process will compile them into the development environment.
In case there are any production bugfixing changes, which must go into the next release, then the new (fixed) revisions of these files should be given the "GO" tag - the release build process will then pick these changes up and compile them for the release SWF.
A more difficult situation is when there are future changes and immediate bugfixes to be performed on the same files. In such situation, branching might be the only answer, though I would do things differently:
The result in CVS might look like this:
This however is complicated if the future changes encompass more than one file, in which case the "GO" revision contents must be restored for all the files involved. In order to make this easier, first tag the future changes with some other tag, such as "NEW", so you'll know which files to restore after you've done bugfixing.
Thats it. I don't know if the above made any sense at all, but this is how I would tackle this code quality issue while keeping a grip on my senses at the same time...
I've previously worked for another organization where the releasing was done very differently. In there, the software was released file-by-file as opposed to by package. When you needed to make some changes to already existing piece of software, you checked out the relevant file(s), modified it (them) and committed the change(s) back, noting what revision did the new file(s) get. After that you created a change document and filled it with the name(s) of the file(s) which were changed, the new revision and the reason for the change. The software releasing team got the change document, checked out the necessary revisions you had written in the document, compiled them and released them.
In my current organization, the releasing is done monthly (sometimes even less frequently) in one big package. In addition to that, our Flex application is submitted also as a package, which we compile ourselves (the resulting SWF is released).
The problem we are facing has to do with release quality. Since the software is released as a package, it becomes vitally important to track which changes to the individual Flex source files get to go into the package and which must be left out, since they are not yet complete. Still, in development environment we need the latest state there is (so called nightly build). The question is - how to track the changes? How to differentiate the changes of the future from the immediate changes scheduled to be released next?
Normally, the development environment is compiled from the HEAD of the CVS - with all the latest changes. Up until recently the same HEAD build was also released. Since we now are doing more and more future developments that do not need to get in anytime soon, that started to create problems for us. For example, in order to demonstrate my new development, I had to commit the changes, so that the nightly build process would build it into the development environment. But this can no longer be the version that goes out as a release version, since my new development should not be released yet... How to solve this?
Some parts of our organization are using extensive branching. Any bugfixing to production code is performed on a branch which is later merged with the HEAD code... this is a very difficult process with lots of errors which we hoped to avoid.
My suggestion was to use a special tag to track the revisions of the source files which are used to compile the release SWF. The tag name might be anything, for example "GO". This tag is given to all the files that are scheduled to go out next - the release build process will only check out files with the "GO" tag (as opposed to the nightly build process, which checks out HEAD).
If there are any future changes which should not go into the next release, then those files are not to be tagged with the "GO" tag, so that tag will remain on the older revision of these files. Hence the release build process will ignore the future changes, while the nightly build process will compile them into the development environment.
In case there are any production bugfixing changes, which must go into the next release, then the new (fixed) revisions of these files should be given the "GO" tag - the release build process will then pick these changes up and compile them for the release SWF.
A more difficult situation is when there are future changes and immediate bugfixes to be performed on the same files. In such situation, branching might be the only answer, though I would do things differently:
- commit any uncommitted future changes (if any) to CVS;
- get the contents of the file revision with the "GO" tag into the current file;
- perform the bugfixing on that code, test the bugfix;
- commit the changes and move the "GO" tag to the new revison you just committed;
- now get the contents of the previous HEAD revision (before the commit in 4 above);
- perform the same bugfixing in this version and commit the changes back to the HEAD.
The result in CVS might look like this:
- r1.4 - the old "GO" revision of the file
- r1.5 - future changes without a tag
- r1.6 - some more future changes without a tag
- r1.7 - the r1.4 revision with the bugfix and with "GO" tag
- r1.8 - the r1.6 revision with the bugfix, with the latest future changes, but without a tag
This however is complicated if the future changes encompass more than one file, in which case the "GO" revision contents must be restored for all the files involved. In order to make this easier, first tag the future changes with some other tag, such as "NEW", so you'll know which files to restore after you've done bugfixing.
Thats it. I don't know if the above made any sense at all, but this is how I would tackle this code quality issue while keeping a grip on my senses at the same time...
Subscribe to:
Posts (Atom)