Пример #1
0
    def migrate(self, pool, source, target):
        """ Replace a device in a btrfs pool.

        Parameters
        ----------
        pool : [str]
            Pool into which the replaced device belongs.
        source : [main.DeviceItem]
            Source device.
        target : [str]
            Path to the target device.
        """
        pool = self._pool[pool]

        if 'mount' not in pool:
            tmp = misc.temp_mount("UUID={0}".format(pool['uuid']))
            pool['mount'] = tmp

        dev = BtrfsDev(options=self.options).data
        command = ['replace', 'start']
        if self.options.force:
            command.extend(['-f'])
        command.extend(['-B', source.name, target, pool['mount']])

        self.run_btrfs(command)
        misc.send_udev_event(target, "change")
        self._udev_checkpoint_fs(pool['pool_name'])
Пример #2
0
 def resize(self, vol, size, resize_fs=True):
     vol = self.data[vol]
     if 'mount' not in vol:
         tmp = misc.temp_mount("UUID={0}".format(vol['uuid']))
         vol['mount'] = tmp
     command = ['filesystem', 'resize', str(int(size)) + "K", vol['mount']]
     self.run_btrfs(command)
Пример #3
0
    def create(self, pool, size=None, name=None, devs=None, options=None):
        options = options or {}
        if pool in self._pool:
            vol = None
            if size or 'raid' in options:
                self.problem.warn("Only name, volume name and pool name " +
                                  "can be specified when creating btrfs " +
                                  "subvolume, the rest will be ignored")
            tmp = misc.temp_mount("UUID={0}".format(self._pool[pool]['uuid']))
            self._pool[pool]['mount'] = tmp

            if not name:
                now = datetime.datetime.now()
                name = now.strftime("%Y-%m-%d-T%H%M%S")
                vol = "{0}/{1}".format(self._pool[pool]['mount'], name)
            elif os.path.isabs(name):
                vol = name
            else:
                vol = "{0}/{1}".format(self._pool[pool]['mount'], name)

            self._check_new_path(vol, name)
            self.run_btrfs(['subvolume', 'create', vol])
            vol = "{0}:{1}".format(pool, name)
        else:
            if len(devs) == 0:
                self.problem.check(self.problem.NO_DEVICES, pool)
            if name:
                self.problem.warn("Creating new pool. Argument (--name " +
                                  "{0}) will be ignored!".format(name))
            vol = self._create_filesystem(pool, pool, devs, size, options)
        return vol
Пример #4
0
 def reduce(self, pool, device):
     pool = self.data[pool]
     if 'mount' not in pool:
         tmp = misc.temp_mount("UUID={0}".format(pool['uuid']))
         pool['mount'] = tmp
     command = ['device', 'delete', device, pool['mount']]
     self.run_btrfs(command)
     self._udev_checkpoint_fs(pool['pool_name'])
Пример #5
0
 def reduce(self, pool, device):
     pool = self.data[pool]
     if 'mount' not in pool:
         tmp = misc.temp_mount("UUID={0}".format(pool['uuid']))
         pool['mount'] = tmp
     command = ['device', 'delete', device, pool['mount']]
     self.run_btrfs(command)
     misc.send_udev_event(device, "change")
Пример #6
0
 def resize(self, vol, size, resize_fs=True):
     vol = self.data[vol]
     if 'mount' not in vol:
         tmp = misc.temp_mount("UUID={0}".format(vol['uuid']))
         vol['mount'] = tmp
     if 'subvolume' in vol and vol['subvolume'] is True:
         self.problem.check(self.problem.NOT_SUPPORTED,
                            'Resizing btrfs subvolume')
     command = ['filesystem', 'resize', str(int(size)) + "K", vol['mount']]
     self.run_btrfs(command)
     self._udev_checkpoint_fs(vol['pool_name'])
Пример #7
0
 def extend(self, pool, devices):
     pool = self.data[pool]
     if 'mount' not in pool:
         tmp = misc.temp_mount("UUID={0}".format(pool['uuid']))
         pool['mount'] = tmp
     if type(devices) is not list:
         devices = [devices]
     command = ['device', 'add']
     command.extend(devices)
     command.append(pool['mount'])
     self.run_btrfs(command)
Пример #8
0
    def snapshot(self, vol, destination, name, snap_size=None):
        vol = self[vol]
        if 'mount' not in vol:
            tmp = misc.temp_mount("UUID={0}".format(vol['uuid']))
            vol['mount'] = tmp

        if not destination and not name:
            now = datetime.datetime.now()
            destination = vol['mount'] + now.strftime("/snap-%Y-%m-%d-T%H%M%S")
        if name:
            destination = vol['mount'] + "/" + name

        if snap_size:
            self.problem.warn("Btrfs doesn't allow setting a size of " +
                              "subvolumes")

        command = ['subvolume', 'snapshot', vol['mount'], destination]
        self.run_btrfs(command)
Пример #9
0
 def remove(self, vol):
     volume = self._vol[vol]
     if 'subvolume' in volume:
         # If subvolume is mounted directly we can not remove it. So ask
         # user whether he wants to umount it. The we'll have to mount the
         # root subvolume and remove this subvolume.
         if 'direct_mount' in volume and volume['direct_mount']:
             if self.problem.check(self.problem.FS_MOUNTED,
                                   [vol, volume['mount']]):
                 misc.do_umount(volume['mount'])
                 del volume['mount']
                 del volume['direct_mount']
         if 'mount' not in volume:
             mount = misc.temp_mount("UUID={0}".format(volume['uuid']))
             path = "{0}/{1}".format(mount, volume['path'])
         else:
             path = volume['mount']
         self.run_btrfs(['subvolume', 'delete', path])
     else:
         self._remove_filesystem(vol)
Пример #10
0
 def extend(self, pool, devices):
     pool = self.data[pool]
     if 'mount' not in pool:
         tmp = misc.temp_mount("UUID={0}".format(pool['uuid']))
         pool['mount'] = tmp
     if type(devices) is not list:
         devices = [devices]
     command = ['device', 'add']
     # This might seem weird, but btrfs is mostly broken when it comes to
     # checking existing signatures because it will for example check for
     # backup superblocks as well, which is wrong. Also we have check for
     # existing file system signatures in the ssm itself. Other things
     # than file system should be covered by the backend and we should
     # have tried to remove the device from the respective pool already.
     # So at this point there should not be any useful signatures to
     # speak of. However as I mentioned btrfs is broken, so force it.
     if self._can_btrfs_force(['btrfs', 'device', 'add']):
         command.extend(['--force'])
     command.extend(devices)
     command.append(pool['mount'])
     self.run_btrfs(command)
     misc.udev_checkpoint(devices)