Novell Home

Shrink NTFS Partition Using AutoYaST

Novell Cool Solutions: Tip
By Kenneth Stevenson

Digg This - Slashdot This

Posted: 9 Feb 2007
 

Problem:

We deploy openSUSE ( 10.0 ) on a variety of hardware using AutoYaST. In many cases it is being added to a machine which already has Windows occupying an NTFS partition spanning the entire disk. There isn't any AutoYaST instructions on how to shrink the NTFS partition.

Solution:

It is possible to use a custom rule in the rules.xml file used by AutoYaST to determine the current disk partitioning and filesystem allocation, conditionally resize partitions and select an appropriate AutoYaST profile.

Example:

<?xml version="1.0"?>
<!DOCTYPE autoinstall SYSTEM "/usr/share/autoinstall/dtd/rules.dtd">
<autoinstall xmlns="http://www.suse.com/1.0/yast2ns" xmlns:config="http://www.su
se.com/1.0/configns">

<!-- architecture based defaults -->
  <rules config:type="list">
    <rule>
      <arch>
        <match>*</match>
      </arch>
      <result>
        <profile>profiles/@arch@.xml</profile>
        <continue config:type="boolean">true</continue>
      </result>
    </rule>

<rule>
    <custom1>
        <script><![CDATA[
#!/bin/sh

cat << EOF > /tmp/pq
p
q
EOF

#Determine primary HDD
# We are rubbish as we only check for first SCSI/IDE disk and give up
# would be better to use hwinfo --disk

fdisk /dev/sda < /tmp/pq 2>&1 | grep "Unable to open" >/dev/null
if [ $? -ne 0 ]
then
PRIHDD=sda
fi

fdisk /dev/hda < /tmp/pq 2>&1 | grep "Unable to open" >/dev/null
if [ $? -ne 0 ]
then
# If PRIHDD is already set we bail
if [ "$PRIHDD" != "" ]
then
echo -n bail
exit
else
PRIHDD=hda
fi
fi

# If PRIHDD is still empty we bail
if [ "$PRIHDD" = "" ]
then
echo -n bail
exit
fi

# Check if drive contains partitions
NUMPART=`fdisk /dev/$PRIHDD < /tmp/pq 2>&1 | grep '^/' | wc -l`

# Check if drive contains NTFS partitions
NUMNTFS=`fdisk /dev/$PRIHDD < /tmp/pq 2>&1 | grep '^/.*HPFS/NTFS' | wc -l`

if [ $NUMNTFS -eq 0 -o $NUMPART -eq 0 ]
then
# Drive contains no partitions or no NTFS so autobuild over it
echo -n $PRIHDD
exit
fi

if [ $NUMPART -gt 1 ]
then
# Drive contains more than one partition and one is NTFS so we bail
echo -n bail
exit
fi

# Obtain total cylinders
TOTCYL=`fdisk /dev/$PRIHDD < /tmp/pq 2>&1 | sed -n '/^[0-9][0-9]* heads/{s/.*\( 
[0-9][0-9]*\) cylinders.*/\1/;s/ //;p}'`

# Grab partition start/end and partition number
PART=`fdisk /dev/$PRIHDD < /tmp/pq 2>&1 | grep ^/ | sed 's/[ \t][ \t]*/:/g'`
DEV=`echo $PART | cut -f1 -d: | cut -f3 -d/`
START=`echo $PART | cut -f3 -d:`
END=`echo $PART | cut -f4 -d:`

# Does partition span entire drive
if [ $START -eq 1 -a $END -ge $((TOTCYL-3)) ]
then
# partition spans full drive
MAXFREE=`ntfsresize -iP /dev/$DEV | sed -n '/^You might resize at/{s/.*freeing \
([^ ]*\).*/\1/;p}'`
# check if there is 10GB + 2GB working space for Windows
if [ $MAXFREE -lt 12000 ]
then
echo -n bail
exit
fi

CURSIZE=`ntfsresize -iP /dev/$DEV | sed -n '/Current volume size/{s/.*(\([^ ]*\)
.*/\1/;p}'`
NEWSIZE=$((CURSIZE-10000))
# test run the resize
ntfsresize -nPs ${NEWSIZE}M /dev/$DEV > /dev/null 2>&1
if [ $? -ne 0 ]
then
# Something went wrong
echo -n bail
exit
fi

ntfsresize -fPs ${NEWSIZE}M /dev/$DEV > /dev/null 2>&1

# fdisk may round down to nearest cylinder boundary, add 140 which is the larges
t cylinder size
NEWSIZE=$((NEWSIZE+140))

fdisk /dev/$PRIHDD << EOF > /dev/null 2>&1
d
n
p
1
1
+${NEWSIZE}M
t
7
a
1
w
EOF

else
# there is already some free space so we will try and install into that
/bin/true
fi

echo -n $PRIHDD-dual
]]>
        </script>
        <match>*</match>
        <match_type>exact</match_type>
    </custom1>
    <result>
         <profile>profiles/@custom1@.xml</profile>
         <continue config:type="boolean">true</continue>
    </result>
</rule>

<!-- machine is Dell Optiplex GX620 -->
    <rule>
      <product>
        <match>OptiPlex GX620</match>
        <match_type>exact</match_type>
      </product>
      <operator>and</operator>
      <product_vendor>
        <match>Dell Inc.</match>
        <match_type>exact</match_type>
      </product_vendor>
      <result>
        <profile>profiles/gx620.xml</profile>
        <continue config:type="boolean">true</continue>
      </result>
    </rule>

<!-- machine is HP DX5150 -->
    <rule>
      <board_vendor>
        <match>MSI</match>
        <match_type>exact</match_type>
      </board_vendor>
      <operator>and</operator>
      <board>
        <match>09AC</match>
        <match_type>exact</match_type>
      </board>
      <operator>and</operator>
      <product_vendor>
        <match>Hewlett-Packard</match>
        <match_type>exact</match_type>
      </product_vendor>
      <result>
        <profile>profiles/dx5150.xml</profile>
        <continue config:type="boolean">true</continue>
      </result>
    </rule>
  </rules>
</autoinstall>




Novell Cool Solutions (corporate web communities) are produced by WebWise Solutions. www.webwiseone.com

© 2014 Novell