Article

Kenneth Stevenson's picture
article
Reads:

3406

Score:
2
2
3
 
Comments:

0

Shrink NTFS Partition Using AutoYaST

(View Disclaimer)

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>




Disclaimer: As with everything else at Cool Solutions, this content is definitely not supported by Novell (so don't even think of calling Support if you try something and it blows up).

It was contributed by a community member and is published "as is." It seems to have worked for at least one person, and might work for you. But please be sure to test, test, test before you do anything drastic with it.




User Comments

© 2012 Novell