]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-volume: support no_systemd with lvm migrate 43048/head
authorDimitri Savineau <dsavinea@redhat.com>
Fri, 3 Sep 2021 16:47:25 +0000 (12:47 -0400)
committerDimitri Savineau <dsavinea@redhat.com>
Fri, 3 Sep 2021 16:53:03 +0000 (12:53 -0400)
The `ceph-volume lvm migrate/new-db/new-wal` commands don't support
running on non systemd systems or within containers.
Like other ceph-volume commands (lvm activate/batch/zap or raw activate)
we also need to be able to use the --no-systemd flag.

Fixes: https://tracker.ceph.com/issues/51854
Signed-off-by: Dimitri Savineau <dsavinea@redhat.com>
doc/man/8/ceph-volume.rst
src/ceph-volume/ceph_volume/devices/lvm/migrate.py
src/ceph-volume/ceph_volume/tests/devices/lvm/test_migrate.py

index 763138ec2e5a6cb7597cd5e7dd91507dbbf0d585..216e272708dd164566edbc12e36b946173febe34 100644 (file)
@@ -383,6 +383,10 @@ Optional arguments:
 
    show the help message and exit
 
+.. option:: --no-systemd
+
+   Skip checking OSD systemd unit
+
 Required arguments:
 
 .. option:: --target
@@ -407,6 +411,10 @@ Optional arguments:
 
    show the help message and exit
 
+.. option:: --no-systemd
+
+   Skip checking OSD systemd unit
+
 Required arguments:
 
 .. option:: --target
@@ -439,6 +447,10 @@ Optional arguments:
 
    show the help message and exit
 
+.. option:: --no-systemd
+
+   Skip checking OSD systemd unit
+
 Required arguments:
 
 .. option:: --from
index 3410dd5087967de98965cdcf0f650e5a8ba6ee23..872fe3dd31b37cfd79c9570efd5a4888d2894c52 100644 (file)
@@ -400,7 +400,7 @@ class Migrate(object):
 
     @decorators.needs_root
     def migrate_osd(self):
-        if self.args.osd_id:
+        if self.args.osd_id and not self.args.no_systemd:
             osd_is_running = systemctl.osd_is_active(self.args.osd_id)
             if osd_is_running:
                 mlogger.error('OSD is running, stop it with: '
@@ -509,6 +509,12 @@ class Migrate(object):
             choices=['data', 'db', 'wal'],
             help='Copy BlueFS data from DB device',
         )
+        parser.add_argument(
+            '--no-systemd',
+            dest='no_systemd',
+            action='store_true',
+            help='Skip checking OSD systemd unit',
+        )
 
         if len(self.argv) == 0:
             print(sub_command_help)
@@ -547,6 +553,12 @@ class NewVolume(object):
             required=True,
             help='Specify target Logical Volume (LV) to attach',
         )
+        parser.add_argument(
+            '--no-systemd',
+            dest='no_systemd',
+            action='store_true',
+            help='Skip checking OSD systemd unit',
+        )
         return parser
 
     @decorators.needs_root
@@ -587,7 +599,7 @@ class NewVolume(object):
 
     @decorators.needs_root
     def new_volume(self):
-        if self.args.osd_id:
+        if self.args.osd_id and not self.args.no_systemd:
             osd_is_running = systemctl.osd_is_active(self.args.osd_id)
             if osd_is_running:
                 mlogger.error('OSD ID is running, stop it with:'
index 86874f2e96f967aac3b6f9b1bd912754121e5506..9eaa76c182fc2691cf45700e055b0f0bf093efef 100644 (file)
@@ -660,6 +660,160 @@ class TestNew(object):
             '--dev-target', '/dev/VolGroup/target_volume',
             '--command', 'bluefs-bdev-new-db']
 
+    def test_newdb_active_systemd(self, is_root, monkeypatch, capsys):
+        source_tags = \
+        'ceph.osd_id=0,ceph.type=data,ceph.osd_fsid=1234,'\
+        'ceph.wal_uuid=wal_uuid,ceph.db_device=/dbdevice'
+        source_wal_tags = \
+        'ceph.wal_uuid=uuid,ceph.wal_device=device,' \
+        'ceph.osd_id=0,ceph.type=wal'
+
+        data_vol = api.Volume(lv_name='volume1', lv_uuid='datauuid',
+                              vg_name='vg',
+                              lv_path='/dev/VolGroup/lv1',
+                              lv_tags=source_tags)
+        wal_vol = api.Volume(lv_name='volume3',
+                             lv_uuid='waluuid',
+                             vg_name='vg',
+                             lv_path='/dev/VolGroup/lv3',
+                             lv_tags=source_wal_tags)
+
+        self.mock_single_volumes = {'/dev/VolGroup/lv1': data_vol,
+                                    '/dev/VolGroup/lv3': wal_vol}
+
+        monkeypatch.setattr(migrate.api, 'get_single_lv',
+            self.mock_get_single_lv)
+
+        self.mock_process_input = []
+        monkeypatch.setattr(process, 'call', self.mock_process)
+
+        self.mock_volume = api.Volume(lv_name='target_volume1', lv_uuid='y',
+                                      vg_name='vg',
+                                      lv_path='/dev/VolGroup/target_volume',
+                                      lv_tags='')
+        monkeypatch.setattr(api, 'get_lv_by_fullname',
+            self.mock_get_lv_by_fullname)
+
+        monkeypatch.setattr("ceph_volume.systemd.systemctl.osd_is_active",
+            lambda id: True)
+
+        #find_associated_devices will call get_lvs() 4 times
+        # and it this needs results to be arranged that way
+        self.mock_volumes = []
+        self.mock_volumes.append([data_vol, wal_vol])
+        self.mock_volumes.append([data_vol])
+        self.mock_volumes.append([])
+        self.mock_volumes.append([wal_vol])
+
+        monkeypatch.setattr(migrate.api, 'get_lvs', self.mock_get_lvs)
+
+        monkeypatch.setattr(migrate, 'get_cluster_name',
+            lambda osd_id, osd_fsid: 'ceph_cluster')
+        monkeypatch.setattr(system, 'chown', lambda path: 0)
+
+        m = migrate.NewDB(argv=[
+            '--osd-id', '1',
+            '--osd-fsid', '55BD4219-16A7-4037-BC20-0F158EFCC83D',
+            '--target', 'vgname/new_db'])
+
+        with pytest.raises(SystemExit) as error:
+            m.main()
+
+        stdout, stderr = capsys.readouterr()
+
+        assert 'Unable to attach new volume for OSD: 1' == str(error.value)
+        assert '--> OSD ID is running, stop it with: systemctl stop ceph-osd@1' == stderr.rstrip()
+        assert not stdout
+
+    def test_newdb_no_systemd(self, is_root, monkeypatch):
+        source_tags = \
+        'ceph.osd_id=0,ceph.type=data,ceph.osd_fsid=1234,'\
+        'ceph.wal_uuid=wal_uuid,ceph.db_device=/dbdevice'
+        source_wal_tags = \
+        'ceph.wal_uuid=uuid,ceph.wal_device=device,' \
+        'ceph.osd_id=0,ceph.type=wal'
+
+        data_vol = api.Volume(lv_name='volume1', lv_uuid='datauuid',
+                              vg_name='vg',
+                              lv_path='/dev/VolGroup/lv1',
+                              lv_tags=source_tags)
+        wal_vol = api.Volume(lv_name='volume3',
+                             lv_uuid='waluuid',
+                             vg_name='vg',
+                             lv_path='/dev/VolGroup/lv3',
+                             lv_tags=source_wal_tags)
+
+        self.mock_single_volumes = {'/dev/VolGroup/lv1': data_vol,
+                                    '/dev/VolGroup/lv3': wal_vol}
+
+        monkeypatch.setattr(migrate.api, 'get_single_lv',
+            self.mock_get_single_lv)
+
+        self.mock_process_input = []
+        monkeypatch.setattr(process, 'call', self.mock_process)
+
+        self.mock_volume = api.Volume(lv_name='target_volume1', lv_uuid='y',
+                                      vg_name='vg',
+                                      lv_path='/dev/VolGroup/target_volume',
+                                      lv_tags='')
+        monkeypatch.setattr(api, 'get_lv_by_fullname',
+            self.mock_get_lv_by_fullname)
+
+        #find_associated_devices will call get_lvs() 4 times
+        # and it this needs results to be arranged that way
+        self.mock_volumes = []
+        self.mock_volumes.append([data_vol, wal_vol])
+        self.mock_volumes.append([data_vol])
+        self.mock_volumes.append([])
+        self.mock_volumes.append([wal_vol])
+
+        monkeypatch.setattr(migrate.api, 'get_lvs', self.mock_get_lvs)
+
+        monkeypatch.setattr(migrate, 'get_cluster_name',
+            lambda osd_id, osd_fsid: 'ceph_cluster')
+        monkeypatch.setattr(system, 'chown', lambda path: 0)
+
+        migrate.NewDB(argv=[
+            '--osd-id', '1',
+            '--osd-fsid', '55BD4219-16A7-4037-BC20-0F158EFCC83D',
+            '--target', 'vgname/new_db',
+            '--no-systemd']).main()
+
+        n = len(self.mock_process_input)
+        assert n >= 5
+
+        assert self.mock_process_input[n - 5] == [
+            'lvchange',
+            '--deltag', 'ceph.db_device=/dbdevice',
+            '/dev/VolGroup/lv1']
+        assert self.mock_process_input[n - 4] == [
+            'lvchange',
+            '--addtag', 'ceph.db_uuid=y',
+            '--addtag', 'ceph.db_device=/dev/VolGroup/target_volume',
+            '/dev/VolGroup/lv1']
+
+        assert self.mock_process_input[n - 3].sort() == [
+            'lvchange',
+            '--addtag', 'ceph.wal_uuid=uuid',
+            '--addtag', 'ceph.osd_id=0',
+            '--addtag', 'ceph.type=db',
+            '--addtag', 'ceph.osd_fsid=1234',
+            '--addtag', 'ceph.db_uuid=y',
+            '--addtag', 'ceph.db_device=/dev/VolGroup/target_volume',
+            '/dev/VolGroup/target_volume'].sort()
+
+        assert self.mock_process_input[n - 2] == [
+            'lvchange',
+            '--addtag', 'ceph.db_uuid=y',
+            '--addtag', 'ceph.db_device=/dev/VolGroup/target_volume',
+            '/dev/VolGroup/lv3']
+
+        assert self.mock_process_input[n - 1] == [
+            'ceph-bluestore-tool',
+            '--path', '/var/lib/ceph/osd/ceph_cluster-1',
+            '--dev-target', '/dev/VolGroup/target_volume',
+            '--command', 'bluefs-bdev-new-db']
+
     @patch('os.getuid')
     def test_newwal(self, m_getuid, monkeypatch, capsys):
         m_getuid.return_value = 0
@@ -726,6 +880,116 @@ class TestNew(object):
             '--dev-target', '/dev/VolGroup/target_volume',
             '--command', 'bluefs-bdev-new-wal']
 
+    def test_newwal_active_systemd(self, is_root, monkeypatch, capsys):
+        source_tags = \
+        'ceph.osd_id=0,ceph.type=data,ceph.osd_fsid=1234'
+
+        data_vol = api.Volume(lv_name='volume1', lv_uuid='datauuid', vg_name='vg',
+                         lv_path='/dev/VolGroup/lv1', lv_tags=source_tags)
+
+        self.mock_single_volumes = {'/dev/VolGroup/lv1': data_vol}
+
+        monkeypatch.setattr(migrate.api, 'get_single_lv', self.mock_get_single_lv)
+
+        self.mock_process_input = []
+        monkeypatch.setattr(process, 'call', self.mock_process)
+
+        self.mock_volume = api.Volume(lv_name='target_volume1', lv_uuid='y', vg_name='vg',
+                                      lv_path='/dev/VolGroup/target_volume',
+                                      lv_tags='')
+        monkeypatch.setattr(api, 'get_lv_by_fullname', self.mock_get_lv_by_fullname)
+
+        monkeypatch.setattr("ceph_volume.systemd.systemctl.osd_is_active", lambda id: True)
+
+        #find_associated_devices will call get_lvs() 4 times
+        # and it this needs results to be arranged that way
+        self.mock_volumes = []
+        self.mock_volumes.append([data_vol])
+        self.mock_volumes.append([data_vol])
+        self.mock_volumes.append([])
+        self.mock_volumes.append([])
+
+        monkeypatch.setattr(migrate.api, 'get_lvs', self.mock_get_lvs)
+
+        monkeypatch.setattr(migrate, 'get_cluster_name', lambda osd_id, osd_fsid: 'cluster')
+        monkeypatch.setattr(system, 'chown', lambda path: 0)
+
+        m = migrate.NewWAL(argv=[
+            '--osd-id', '2',
+            '--osd-fsid', '55BD4219-16A7-4037-BC20-0F158EFCC83D',
+            '--target', 'vgname/new_wal'])
+
+        with pytest.raises(SystemExit) as error:
+            m.main()
+
+        stdout, stderr = capsys.readouterr()
+
+        assert 'Unable to attach new volume for OSD: 2' == str(error.value)
+        assert '--> OSD ID is running, stop it with: systemctl stop ceph-osd@2' == stderr.rstrip()
+        assert not stdout
+
+    def test_newwal_no_systemd(self, is_root, monkeypatch):
+        source_tags = \
+        'ceph.osd_id=0,ceph.type=data,ceph.osd_fsid=1234'
+
+        data_vol = api.Volume(lv_name='volume1', lv_uuid='datauuid', vg_name='vg',
+                         lv_path='/dev/VolGroup/lv1', lv_tags=source_tags)
+
+        self.mock_single_volumes = {'/dev/VolGroup/lv1': data_vol}
+
+        monkeypatch.setattr(migrate.api, 'get_single_lv', self.mock_get_single_lv)
+
+        self.mock_process_input = []
+        monkeypatch.setattr(process, 'call', self.mock_process)
+
+        self.mock_volume = api.Volume(lv_name='target_volume1', lv_uuid='y', vg_name='vg',
+                                      lv_path='/dev/VolGroup/target_volume',
+                                      lv_tags='')
+        monkeypatch.setattr(api, 'get_lv_by_fullname', self.mock_get_lv_by_fullname)
+
+        #find_associated_devices will call get_lvs() 4 times
+        # and it this needs results to be arranged that way
+        self.mock_volumes = []
+        self.mock_volumes.append([data_vol])
+        self.mock_volumes.append([data_vol])
+        self.mock_volumes.append([])
+        self.mock_volumes.append([])
+
+        monkeypatch.setattr(migrate.api, 'get_lvs', self.mock_get_lvs)
+
+        monkeypatch.setattr(migrate, 'get_cluster_name', lambda osd_id, osd_fsid: 'cluster')
+        monkeypatch.setattr(system, 'chown', lambda path: 0)
+
+        migrate.NewWAL(argv=[
+            '--osd-id', '2',
+            '--osd-fsid', '55BD4219-16A7-4037-BC20-0F158EFCC83D',
+            '--target', 'vgname/new_wal',
+            '--no-systemd']).main()
+
+        n = len(self.mock_process_input)
+        assert n >= 3
+
+        assert self.mock_process_input[n - 3] == [
+            'lvchange',
+            '--addtag', 'ceph.wal_uuid=y',
+            '--addtag', 'ceph.wal_device=/dev/VolGroup/target_volume',
+            '/dev/VolGroup/lv1']
+
+        assert self.mock_process_input[n - 2].sort() == [
+            'lvchange',
+            '--addtag', 'ceph.osd_id=0',
+            '--addtag', 'ceph.type=wal',
+            '--addtag', 'ceph.osd_fsid=1234',
+            '--addtag', 'ceph.wal_uuid=y',
+            '--addtag', 'ceph.wal_device=/dev/VolGroup/target_volume',
+            '/dev/VolGroup/target_volume'].sort()
+
+        assert self.mock_process_input[n - 1] == [
+            'ceph-bluestore-tool',
+            '--path', '/var/lib/ceph/osd/cluster-2',
+            '--dev-target', '/dev/VolGroup/target_volume',
+            '--command', 'bluefs-bdev-new-wal']
+
 class TestMigrate(object):
 
     mock_volume = None
@@ -923,16 +1187,11 @@ class TestMigrate(object):
             '--devs-source', '/var/lib/ceph/osd/ceph-2/block',
             '--devs-source', '/var/lib/ceph/osd/ceph-2/block.db']
 
-    @patch('os.getuid')
-    def test_migrate_data_db_to_new_db_skip_wal(self, m_getuid, monkeypatch):
-        m_getuid.return_value = 0
-
+    def test_migrate_data_db_to_new_db_active_systemd(self, is_root, monkeypatch, capsys):
         source_tags = 'ceph.osd_id=2,ceph.type=data,ceph.osd_fsid=1234,' \
         'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
         source_db_tags = 'ceph.osd_id=2,ceph.type=db,ceph.osd_fsid=1234,' \
         'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
-        source_wal_tags = 'ceph.osd_id=2,ceph.type=wal,ceph.osd_fsid=1234' \
-        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
 
         data_vol = api.Volume(lv_name='volume1',
                               lv_uuid='datauuid',
@@ -945,11 +1204,175 @@ class TestMigrate(object):
                             lv_path='/dev/VolGroup/lv2',
                             lv_tags=source_db_tags)
 
-        wal_vol = api.Volume(lv_name='volume3',
-                             lv_uuid='datauuid',
-                             vg_name='vg',
-                             lv_path='/dev/VolGroup/lv3',
-                             lv_tags=source_wal_tags)
+        self.mock_single_volumes = {
+            '/dev/VolGroup/lv1': data_vol,
+            '/dev/VolGroup/lv2': db_vol,
+        }
+        monkeypatch.setattr(migrate.api, 'get_single_lv',
+            self.mock_get_single_lv)
+
+        self.mock_volume = api.Volume(lv_name='volume2_new', lv_uuid='new-db-uuid',
+                                      vg_name='vg',
+                                      lv_path='/dev/VolGroup/lv2_new',
+                                      lv_tags='')
+        monkeypatch.setattr(api, 'get_lv_by_fullname',
+            self.mock_get_lv_by_fullname)
+
+        self.mock_process_input = []
+        monkeypatch.setattr(process, 'call', self.mock_process)
+
+        devices = []
+        devices.append([Device('/dev/VolGroup/lv1'), 'block'])
+        devices.append([Device('/dev/VolGroup/lv2'), 'db'])
+
+        monkeypatch.setattr(migrate, 'find_associated_devices',
+            lambda osd_id, osd_fsid: devices)
+
+
+        monkeypatch.setattr("ceph_volume.systemd.systemctl.osd_is_active",
+            lambda id: True)
+
+        monkeypatch.setattr(migrate, 'get_cluster_name',
+            lambda osd_id, osd_fsid: 'ceph')
+        monkeypatch.setattr(system, 'chown', lambda path: 0)
+        m = migrate.Migrate(argv=[
+            '--osd-id', '2',
+            '--osd-fsid', '1234',
+            '--from', 'data', 'db', 'wal',
+            '--target', 'vgname/new_wal'])
+
+        with pytest.raises(SystemExit) as error:
+            m.main()
+
+        stdout, stderr = capsys.readouterr()
+
+        assert 'Unable to migrate devices associated with OSD ID: 2' == str(error.value)
+        assert '--> OSD is running, stop it with: systemctl stop ceph-osd@2' == stderr.rstrip()
+        assert not stdout
+
+    def test_migrate_data_db_to_new_db_no_systemd(self, is_root, monkeypatch):
+        source_tags = 'ceph.osd_id=2,ceph.type=data,ceph.osd_fsid=1234,' \
+        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
+        source_db_tags = 'ceph.osd_id=2,ceph.type=db,ceph.osd_fsid=1234,' \
+        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
+
+        data_vol = api.Volume(lv_name='volume1',
+                              lv_uuid='datauuid',
+                              vg_name='vg',
+                              lv_path='/dev/VolGroup/lv1',
+                              lv_tags=source_tags)
+        db_vol = api.Volume(lv_name='volume2',
+                            lv_uuid='dbuuid',
+                            vg_name='vg',
+                            lv_path='/dev/VolGroup/lv2',
+                            lv_tags=source_db_tags)
+
+        self.mock_single_volumes = {
+            '/dev/VolGroup/lv1': data_vol,
+            '/dev/VolGroup/lv2': db_vol,
+        }
+        monkeypatch.setattr(migrate.api, 'get_single_lv',
+            self.mock_get_single_lv)
+
+        self.mock_volume = api.Volume(lv_name='volume2_new', lv_uuid='new-db-uuid',
+                                      vg_name='vg',
+                                      lv_path='/dev/VolGroup/lv2_new',
+                                      lv_tags='')
+        monkeypatch.setattr(api, 'get_lv_by_fullname',
+            self.mock_get_lv_by_fullname)
+
+        self.mock_process_input = []
+        monkeypatch.setattr(process, 'call', self.mock_process)
+
+        devices = []
+        devices.append([Device('/dev/VolGroup/lv1'), 'block'])
+        devices.append([Device('/dev/VolGroup/lv2'), 'db'])
+
+        monkeypatch.setattr(migrate, 'find_associated_devices',
+            lambda osd_id, osd_fsid: devices)
+
+
+        monkeypatch.setattr(migrate, 'get_cluster_name',
+            lambda osd_id, osd_fsid: 'ceph')
+        monkeypatch.setattr(system, 'chown', lambda path: 0)
+        m = migrate.Migrate(argv=[
+            '--osd-id', '2',
+            '--osd-fsid', '1234',
+            '--from', 'data', 'db', 'wal',
+            '--target', 'vgname/new_wal',
+            '--no-systemd'])
+        m.main()
+
+        n = len(self.mock_process_input)
+        assert n >= 5
+
+        assert self. mock_process_input[n-5] == [
+            'lvchange',
+            '--deltag', 'ceph.osd_id=2',
+            '--deltag', 'ceph.type=db',
+            '--deltag', 'ceph.osd_fsid=1234',
+            '--deltag', 'ceph.cluster_name=ceph',
+            '--deltag', 'ceph.db_uuid=dbuuid',
+            '--deltag', 'ceph.db_device=db_dev',
+            '/dev/VolGroup/lv2']
+
+        assert self. mock_process_input[n-4] == [
+            'lvchange',
+            '--deltag', 'ceph.db_uuid=dbuuid',
+            '--deltag', 'ceph.db_device=db_dev',
+            '/dev/VolGroup/lv1']
+
+        assert self. mock_process_input[n-3] == [
+            'lvchange',
+            '--addtag', 'ceph.db_uuid=new-db-uuid',
+            '--addtag', 'ceph.db_device=/dev/VolGroup/lv2_new',
+            '/dev/VolGroup/lv1']
+
+        assert self. mock_process_input[n-2] == [
+            'lvchange',
+            '--addtag', 'ceph.osd_id=2',
+            '--addtag', 'ceph.type=db',
+            '--addtag', 'ceph.osd_fsid=1234',
+            '--addtag', 'ceph.cluster_name=ceph',
+            '--addtag', 'ceph.db_uuid=new-db-uuid',
+            '--addtag', 'ceph.db_device=/dev/VolGroup/lv2_new',
+            '/dev/VolGroup/lv2_new']
+
+        assert self. mock_process_input[n-1] == [
+            'ceph-bluestore-tool',
+            '--path', '/var/lib/ceph/osd/ceph-2',
+            '--dev-target', '/dev/VolGroup/lv2_new',
+            '--command', 'bluefs-bdev-migrate',
+            '--devs-source', '/var/lib/ceph/osd/ceph-2/block',
+            '--devs-source', '/var/lib/ceph/osd/ceph-2/block.db']
+
+    @patch('os.getuid')
+    def test_migrate_data_db_to_new_db_skip_wal(self, m_getuid, monkeypatch):
+        m_getuid.return_value = 0
+
+        source_tags = 'ceph.osd_id=2,ceph.type=data,ceph.osd_fsid=1234,' \
+        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
+        source_db_tags = 'ceph.osd_id=2,ceph.type=db,ceph.osd_fsid=1234,' \
+        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
+        source_wal_tags = 'ceph.osd_id=2,ceph.type=wal,ceph.osd_fsid=1234' \
+        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
+
+        data_vol = api.Volume(lv_name='volume1',
+                              lv_uuid='datauuid',
+                              vg_name='vg',
+                              lv_path='/dev/VolGroup/lv1',
+                              lv_tags=source_tags)
+        db_vol = api.Volume(lv_name='volume2',
+                            lv_uuid='dbuuid',
+                            vg_name='vg',
+                            lv_path='/dev/VolGroup/lv2',
+                            lv_tags=source_db_tags)
+
+        wal_vol = api.Volume(lv_name='volume3',
+                             lv_uuid='datauuid',
+                             vg_name='vg',
+                             lv_path='/dev/VolGroup/lv3',
+                             lv_tags=source_wal_tags)
 
         self.mock_single_volumes = {
             '/dev/VolGroup/lv1': data_vol,
@@ -1046,7 +1469,281 @@ class TestMigrate(object):
             '--devs-source', '/var/lib/ceph/osd/ceph-2/block.db']
 
     @patch('os.getuid')
-    def test_migrate_data_db_wal_to_new_db(self, m_getuid, monkeypatch):
+    def test_migrate_data_db_wal_to_new_db(self, m_getuid, monkeypatch):
+        m_getuid.return_value = 0
+
+        source_tags = 'ceph.osd_id=2,ceph.type=data,ceph.osd_fsid=1234,' \
+        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
+        'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
+        source_db_tags = 'ceph.osd_id=2,ceph.type=db,ceph.osd_fsid=1234,' \
+        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
+        source_wal_tags = 'ceph.osd_id=0,ceph.type=wal,ceph.osd_fsid=1234,' \
+        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
+        'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
+
+        data_vol = api.Volume(lv_name='volume1',
+                              lv_uuid='datauuid',
+                              vg_name='vg',
+                              lv_path='/dev/VolGroup/lv1',
+                              lv_tags=source_tags)
+        db_vol = api.Volume(lv_name='volume2',
+                            lv_uuid='dbuuid',
+                            vg_name='vg',
+                            lv_path='/dev/VolGroup/lv2',
+                            lv_tags=source_db_tags)
+
+        wal_vol = api.Volume(lv_name='volume3',
+                             lv_uuid='waluuid',
+                             vg_name='vg',
+                             lv_path='/dev/VolGroup/lv3',
+                             lv_tags=source_wal_tags)
+
+        self.mock_single_volumes = {
+            '/dev/VolGroup/lv1': data_vol,
+            '/dev/VolGroup/lv2': db_vol,
+            '/dev/VolGroup/lv3': wal_vol,
+        }
+        monkeypatch.setattr(migrate.api, 'get_single_lv',
+            self.mock_get_single_lv)
+
+        self.mock_volume = api.Volume(lv_name='volume2_new', lv_uuid='new-db-uuid',
+                                      vg_name='vg',
+                                      lv_path='/dev/VolGroup/lv2_new',
+                                      lv_tags='')
+        monkeypatch.setattr(api, 'get_lv_by_fullname',
+            self.mock_get_lv_by_fullname)
+
+        self.mock_process_input = []
+        monkeypatch.setattr(process, 'call', self.mock_process)
+
+        devices = []
+        devices.append([Device('/dev/VolGroup/lv1'), 'block'])
+        devices.append([Device('/dev/VolGroup/lv2'), 'db'])
+        devices.append([Device('/dev/VolGroup/lv3'), 'wal'])
+
+        monkeypatch.setattr(migrate, 'find_associated_devices',
+            lambda osd_id, osd_fsid: devices)
+
+        monkeypatch.setattr("ceph_volume.systemd.systemctl.osd_is_active",
+            lambda id: False)
+
+        monkeypatch.setattr(migrate, 'get_cluster_name',
+            lambda osd_id, osd_fsid: 'ceph')
+        monkeypatch.setattr(system, 'chown', lambda path: 0)
+        m = migrate.Migrate(argv=[
+            '--osd-id', '2',
+            '--osd-fsid', '1234',
+            '--from', 'data', 'db', 'wal',
+            '--target', 'vgname/new_wal'])
+        m.main()
+
+        n = len(self.mock_process_input)
+        assert n >= 6
+
+        assert self. mock_process_input[n-6] == [
+            'lvchange',
+            '--deltag', 'ceph.osd_id=2',
+            '--deltag', 'ceph.type=db',
+            '--deltag', 'ceph.osd_fsid=1234',
+            '--deltag', 'ceph.cluster_name=ceph',
+            '--deltag', 'ceph.db_uuid=dbuuid',
+            '--deltag', 'ceph.db_device=db_dev',
+            '/dev/VolGroup/lv2']
+
+        assert self. mock_process_input[n-5] == [
+            'lvchange',
+            '--deltag', 'ceph.osd_id=0',
+            '--deltag', 'ceph.type=wal',
+            '--deltag', 'ceph.osd_fsid=1234',
+            '--deltag', 'ceph.cluster_name=ceph',
+            '--deltag', 'ceph.db_uuid=dbuuid',
+            '--deltag', 'ceph.db_device=db_dev',
+            '--deltag', 'ceph.wal_uuid=waluuid',
+            '--deltag', 'ceph.wal_device=wal_dev',
+            '/dev/VolGroup/lv3']
+
+        assert self. mock_process_input[n-4] == [
+            'lvchange',
+            '--deltag', 'ceph.db_uuid=dbuuid',
+            '--deltag', 'ceph.db_device=db_dev',
+            '--deltag', 'ceph.wal_uuid=waluuid',
+            '--deltag', 'ceph.wal_device=wal_dev',
+            '/dev/VolGroup/lv1']
+
+        assert self. mock_process_input[n-3] == [
+            'lvchange',
+            '--addtag', 'ceph.db_uuid=new-db-uuid',
+            '--addtag', 'ceph.db_device=/dev/VolGroup/lv2_new',
+            '/dev/VolGroup/lv1']
+
+        assert self. mock_process_input[n-2] == [
+            'lvchange',
+            '--addtag', 'ceph.osd_id=2',
+            '--addtag', 'ceph.type=db',
+            '--addtag', 'ceph.osd_fsid=1234',
+            '--addtag', 'ceph.cluster_name=ceph',
+            '--addtag', 'ceph.db_uuid=new-db-uuid',
+            '--addtag', 'ceph.db_device=/dev/VolGroup/lv2_new',
+            '/dev/VolGroup/lv2_new']
+
+        assert self. mock_process_input[n-1] == [
+            'ceph-bluestore-tool',
+            '--path', '/var/lib/ceph/osd/ceph-2',
+            '--dev-target', '/dev/VolGroup/lv2_new',
+            '--command', 'bluefs-bdev-migrate',
+            '--devs-source', '/var/lib/ceph/osd/ceph-2/block',
+            '--devs-source', '/var/lib/ceph/osd/ceph-2/block.db',
+            '--devs-source', '/var/lib/ceph/osd/ceph-2/block.wal']
+
+    @patch('os.getuid')
+    def test_dont_migrate_data_db_wal_to_new_data(self,
+                                                  m_getuid,
+                                                  monkeypatch,
+                                                  capsys):
+        m_getuid.return_value = 0
+
+        source_tags = 'ceph.osd_id=2,ceph.type=data,ceph.osd_fsid=1234,' \
+        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
+        source_db_tags = 'ceph.osd_id=2,ceph.type=db,ceph.osd_fsid=1234,' \
+        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
+
+        data_vol = api.Volume(lv_name='volume1',
+                              lv_uuid='datauuid',
+                              vg_name='vg',
+                              lv_path='/dev/VolGroup/lv1',
+                              lv_tags=source_tags)
+        db_vol = api.Volume(lv_name='volume2',
+                            lv_uuid='dbuuid',
+                            vg_name='vg',
+                            lv_path='/dev/VolGroup/lv2',
+                            lv_tags=source_db_tags)
+
+        self.mock_single_volumes = {
+            '/dev/VolGroup/lv1': data_vol,
+            '/dev/VolGroup/lv2': db_vol,
+        }
+        monkeypatch.setattr(migrate.api, 'get_single_lv',
+            self.mock_get_single_lv)
+
+        self.mock_volume = api.Volume(lv_name='volume2_new', lv_uuid='new-db-uuid',
+                                      vg_name='vg',
+                                      lv_path='/dev/VolGroup/lv2_new',
+                                      lv_tags='')
+        monkeypatch.setattr(api, 'get_lv_by_fullname',
+            self.mock_get_lv_by_fullname)
+
+        self.mock_process_input = []
+        monkeypatch.setattr(process, 'call', self.mock_process)
+
+        devices = []
+        devices.append([Device('/dev/VolGroup/lv1'), 'block'])
+        devices.append([Device('/dev/VolGroup/lv2'), 'db'])
+
+        monkeypatch.setattr(migrate, 'find_associated_devices',
+            lambda osd_id, osd_fsid: devices)
+
+        monkeypatch.setattr("ceph_volume.systemd.systemctl.osd_is_active",
+            lambda id: False)
+
+        monkeypatch.setattr(migrate, 'get_cluster_name',
+            lambda osd_id, osd_fsid: 'ceph')
+        monkeypatch.setattr(system, 'chown', lambda path: 0)
+        m = migrate.Migrate(argv=[
+            '--osd-id', '2',
+            '--osd-fsid', '1234',
+            '--from', 'data',
+            '--target', 'vgname/new_data'])
+
+        with pytest.raises(SystemExit) as error:
+            m.main()
+        stdout, stderr = capsys.readouterr()
+        expected = 'Unable to migrate to : vgname/new_data'
+        assert expected in str(error.value)
+        expected = 'Unable to determine new volume type,'
+        ' please use new-db or new-wal command before.'
+        assert expected in stderr
+
+    @patch('os.getuid')
+    def test_dont_migrate_db_to_wal(self,
+                                    m_getuid,
+                                    monkeypatch,
+                                    capsys):
+        m_getuid.return_value = 0
+
+        source_tags = 'ceph.osd_id=2,ceph.type=data,ceph.osd_fsid=1234,' \
+        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
+        'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
+        source_db_tags = 'ceph.osd_id=2,ceph.type=db,ceph.osd_fsid=1234,' \
+        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
+        source_wal_tags = 'ceph.osd_id=2,ceph.type=wal,ceph.osd_fsid=1234,' \
+        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
+        'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
+
+        data_vol = api.Volume(lv_name='volume1',
+                              lv_uuid='datauuid',
+                              vg_name='vg',
+                              lv_path='/dev/VolGroup/lv1',
+                              lv_tags=source_tags)
+        db_vol = api.Volume(lv_name='volume2',
+                            lv_uuid='dbuuid',
+                            vg_name='vg',
+                            lv_path='/dev/VolGroup/lv2',
+                            lv_tags=source_db_tags)
+
+        wal_vol = api.Volume(lv_name='volume3',
+                             lv_uuid='waluuid',
+                             vg_name='vg',
+                             lv_path='/dev/VolGroup/lv3',
+                             lv_tags=source_wal_tags)
+
+        self.mock_single_volumes = {
+            '/dev/VolGroup/lv1': data_vol,
+            '/dev/VolGroup/lv2': db_vol,
+            '/dev/VolGroup/lv3': wal_vol,
+        }
+        monkeypatch.setattr(migrate.api, 'get_single_lv',
+            self.mock_get_single_lv)
+
+        self.mock_volume = wal_vol
+        monkeypatch.setattr(api, 'get_lv_by_fullname',
+            self.mock_get_lv_by_fullname)
+
+        self.mock_process_input = []
+        monkeypatch.setattr(process, 'call', self.mock_process)
+
+        devices = []
+        devices.append([Device('/dev/VolGroup/lv1'), 'block'])
+        devices.append([Device('/dev/VolGroup/lv2'), 'db'])
+        devices.append([Device('/dev/VolGroup/lv3'), 'wal'])
+
+        monkeypatch.setattr(migrate, 'find_associated_devices',
+            lambda osd_id, osd_fsid: devices)
+
+        monkeypatch.setattr("ceph_volume.systemd.systemctl.osd_is_active",
+            lambda id: False)
+
+        monkeypatch.setattr(migrate, 'get_cluster_name',
+            lambda osd_id, osd_fsid: 'ceph')
+        monkeypatch.setattr(system, 'chown', lambda path: 0)
+        m = migrate.Migrate(argv=[
+            '--osd-id', '2',
+            '--osd-fsid', '1234',
+            '--from', 'db',
+            '--target', 'vgname/wal'])
+
+        with pytest.raises(SystemExit) as error:
+            m.main()
+        stdout, stderr = capsys.readouterr()
+        expected = 'Unable to migrate to : vgname/wal'
+        assert expected in str(error.value)
+        expected = 'Migrate to WAL is not supported'
+        assert expected in stderr
+
+    @patch('os.getuid')
+    def test_migrate_data_db_to_db(self,
+                                    m_getuid,
+                                    monkeypatch,
+                                    capsys):
         m_getuid.return_value = 0
 
         source_tags = 'ceph.osd_id=2,ceph.type=data,ceph.osd_fsid=1234,' \
@@ -1054,7 +1751,7 @@ class TestMigrate(object):
         'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
         source_db_tags = 'ceph.osd_id=2,ceph.type=db,ceph.osd_fsid=1234,' \
         'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
-        source_wal_tags = 'ceph.osd_id=0,ceph.type=wal,ceph.osd_fsid=1234,' \
+        source_wal_tags = 'ceph.osd_id=2,ceph.type=wal,ceph.osd_fsid=1234,' \
         'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
         'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
 
@@ -1083,10 +1780,7 @@ class TestMigrate(object):
         monkeypatch.setattr(migrate.api, 'get_single_lv',
             self.mock_get_single_lv)
 
-        self.mock_volume = api.Volume(lv_name='volume2_new', lv_uuid='new-db-uuid',
-                                      vg_name='vg',
-                                      lv_path='/dev/VolGroup/lv2_new',
-                                      lv_tags='')
+        self.mock_volume = db_vol
         monkeypatch.setattr(api, 'get_lv_by_fullname',
             self.mock_get_lv_by_fullname)
 
@@ -1110,79 +1804,32 @@ class TestMigrate(object):
         m = migrate.Migrate(argv=[
             '--osd-id', '2',
             '--osd-fsid', '1234',
-            '--from', 'data', 'db', 'wal',
-            '--target', 'vgname/new_wal'])
+            '--from', 'db', 'data',
+            '--target', 'vgname/db'])
+
         m.main()
 
         n = len(self.mock_process_input)
-        assert n >= 6
-
-        assert self. mock_process_input[n-6] == [
-            'lvchange',
-            '--deltag', 'ceph.osd_id=2',
-            '--deltag', 'ceph.type=db',
-            '--deltag', 'ceph.osd_fsid=1234',
-            '--deltag', 'ceph.cluster_name=ceph',
-            '--deltag', 'ceph.db_uuid=dbuuid',
-            '--deltag', 'ceph.db_device=db_dev',
-            '/dev/VolGroup/lv2']
-
-        assert self. mock_process_input[n-5] == [
-            'lvchange',
-            '--deltag', 'ceph.osd_id=0',
-            '--deltag', 'ceph.type=wal',
-            '--deltag', 'ceph.osd_fsid=1234',
-            '--deltag', 'ceph.cluster_name=ceph',
-            '--deltag', 'ceph.db_uuid=dbuuid',
-            '--deltag', 'ceph.db_device=db_dev',
-            '--deltag', 'ceph.wal_uuid=waluuid',
-            '--deltag', 'ceph.wal_device=wal_dev',
-            '/dev/VolGroup/lv3']
-
-        assert self. mock_process_input[n-4] == [
-            'lvchange',
-            '--deltag', 'ceph.db_uuid=dbuuid',
-            '--deltag', 'ceph.db_device=db_dev',
-            '--deltag', 'ceph.wal_uuid=waluuid',
-            '--deltag', 'ceph.wal_device=wal_dev',
-            '/dev/VolGroup/lv1']
-
-        assert self. mock_process_input[n-3] == [
-            'lvchange',
-            '--addtag', 'ceph.db_uuid=new-db-uuid',
-            '--addtag', 'ceph.db_device=/dev/VolGroup/lv2_new',
-            '/dev/VolGroup/lv1']
-
-        assert self. mock_process_input[n-2] == [
-            'lvchange',
-            '--addtag', 'ceph.osd_id=2',
-            '--addtag', 'ceph.type=db',
-            '--addtag', 'ceph.osd_fsid=1234',
-            '--addtag', 'ceph.cluster_name=ceph',
-            '--addtag', 'ceph.db_uuid=new-db-uuid',
-            '--addtag', 'ceph.db_device=/dev/VolGroup/lv2_new',
-            '/dev/VolGroup/lv2_new']
+        assert n >= 1
+        for s in self.mock_process_input:
+            print(s)
 
         assert self. mock_process_input[n-1] == [
             'ceph-bluestore-tool',
             '--path', '/var/lib/ceph/osd/ceph-2',
-            '--dev-target', '/dev/VolGroup/lv2_new',
+            '--dev-target', '/var/lib/ceph/osd/ceph-2/block.db',
             '--command', 'bluefs-bdev-migrate',
-            '--devs-source', '/var/lib/ceph/osd/ceph-2/block',
-            '--devs-source', '/var/lib/ceph/osd/ceph-2/block.db',
-            '--devs-source', '/var/lib/ceph/osd/ceph-2/block.wal']
-
-    @patch('os.getuid')
-    def test_dont_migrate_data_db_wal_to_new_data(self,
-                                                  m_getuid,
-                                                  monkeypatch,
-                                                  capsys):
-        m_getuid.return_value = 0
+            '--devs-source', '/var/lib/ceph/osd/ceph-2/block']
 
+    def test_migrate_data_db_to_db_active_systemd(self, is_root, monkeypatch, capsys):
         source_tags = 'ceph.osd_id=2,ceph.type=data,ceph.osd_fsid=1234,' \
-        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
+        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
+        'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
         source_db_tags = 'ceph.osd_id=2,ceph.type=db,ceph.osd_fsid=1234,' \
         'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
+        source_wal_tags = 'ceph.osd_id=2,ceph.type=wal,ceph.osd_fsid=1234,' \
+        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
+        'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
 
         data_vol = api.Volume(lv_name='volume1',
                               lv_uuid='datauuid',
@@ -1195,17 +1842,21 @@ class TestMigrate(object):
                             lv_path='/dev/VolGroup/lv2',
                             lv_tags=source_db_tags)
 
+        wal_vol = api.Volume(lv_name='volume3',
+                             lv_uuid='waluuid',
+                             vg_name='vg',
+                             lv_path='/dev/VolGroup/lv3',
+                             lv_tags=source_wal_tags)
+
         self.mock_single_volumes = {
             '/dev/VolGroup/lv1': data_vol,
             '/dev/VolGroup/lv2': db_vol,
+            '/dev/VolGroup/lv3': wal_vol,
         }
         monkeypatch.setattr(migrate.api, 'get_single_lv',
             self.mock_get_single_lv)
 
-        self.mock_volume = api.Volume(lv_name='volume2_new', lv_uuid='new-db-uuid',
-                                      vg_name='vg',
-                                      lv_path='/dev/VolGroup/lv2_new',
-                                      lv_tags='')
+        self.mock_volume = db_vol
         monkeypatch.setattr(api, 'get_lv_by_fullname',
             self.mock_get_lv_by_fullname)
 
@@ -1215,12 +1866,13 @@ class TestMigrate(object):
         devices = []
         devices.append([Device('/dev/VolGroup/lv1'), 'block'])
         devices.append([Device('/dev/VolGroup/lv2'), 'db'])
+        devices.append([Device('/dev/VolGroup/lv3'), 'wal'])
 
         monkeypatch.setattr(migrate, 'find_associated_devices',
             lambda osd_id, osd_fsid: devices)
 
         monkeypatch.setattr("ceph_volume.systemd.systemctl.osd_is_active",
-            lambda id: False)
+            lambda id: True)
 
         monkeypatch.setattr(migrate, 'get_cluster_name',
             lambda osd_id, osd_fsid: 'ceph')
@@ -1228,25 +1880,19 @@ class TestMigrate(object):
         m = migrate.Migrate(argv=[
             '--osd-id', '2',
             '--osd-fsid', '1234',
-            '--from', 'data',
-            '--target', 'vgname/new_data'])
+            '--from', 'db', 'data',
+            '--target', 'vgname/db'])
 
         with pytest.raises(SystemExit) as error:
             m.main()
+
         stdout, stderr = capsys.readouterr()
-        expected = 'Unable to migrate to : vgname/new_data'
-        assert expected in str(error.value)
-        expected = 'Unable to determine new volume type,'
-        ' please use new-db or new-wal command before.'
-        assert expected in stderr
 
-    @patch('os.getuid')
-    def test_dont_migrate_db_to_wal(self,
-                                    m_getuid,
-                                    monkeypatch,
-                                    capsys):
-        m_getuid.return_value = 0
+        assert 'Unable to migrate devices associated with OSD ID: 2' == str(error.value)
+        assert '--> OSD is running, stop it with: systemctl stop ceph-osd@2' == stderr.rstrip()
+        assert not stdout
 
+    def test_migrate_data_db_to_db_no_systemd(self, is_root, monkeypatch):
         source_tags = 'ceph.osd_id=2,ceph.type=data,ceph.osd_fsid=1234,' \
         'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
         'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
@@ -1281,7 +1927,7 @@ class TestMigrate(object):
         monkeypatch.setattr(migrate.api, 'get_single_lv',
             self.mock_get_single_lv)
 
-        self.mock_volume = wal_vol
+        self.mock_volume = db_vol
         monkeypatch.setattr(api, 'get_lv_by_fullname',
             self.mock_get_lv_by_fullname)
 
@@ -1296,28 +1942,32 @@ class TestMigrate(object):
         monkeypatch.setattr(migrate, 'find_associated_devices',
             lambda osd_id, osd_fsid: devices)
 
-        monkeypatch.setattr("ceph_volume.systemd.systemctl.osd_is_active",
-            lambda id: False)
-
         monkeypatch.setattr(migrate, 'get_cluster_name',
             lambda osd_id, osd_fsid: 'ceph')
         monkeypatch.setattr(system, 'chown', lambda path: 0)
         m = migrate.Migrate(argv=[
             '--osd-id', '2',
             '--osd-fsid', '1234',
-            '--from', 'db',
-            '--target', 'vgname/wal'])
+            '--from', 'db', 'data',
+            '--target', 'vgname/db',
+            '--no-systemd'])
 
-        with pytest.raises(SystemExit) as error:
-            m.main()
-        stdout, stderr = capsys.readouterr()
-        expected = 'Unable to migrate to : vgname/wal'
-        assert expected in str(error.value)
-        expected = 'Migrate to WAL is not supported'
-        assert expected in stderr
+        m.main()
+
+        n = len(self.mock_process_input)
+        assert n >= 1
+        for s in self.mock_process_input:
+            print(s)
+
+        assert self. mock_process_input[n-1] == [
+            'ceph-bluestore-tool',
+            '--path', '/var/lib/ceph/osd/ceph-2',
+            '--dev-target', '/var/lib/ceph/osd/ceph-2/block.db',
+            '--command', 'bluefs-bdev-migrate',
+            '--devs-source', '/var/lib/ceph/osd/ceph-2/block']
 
     @patch('os.getuid')
-    def test_migrate_data_db_to_db(self,
+    def test_migrate_data_wal_to_db(self,
                                     m_getuid,
                                     monkeypatch,
                                     capsys):
@@ -1327,7 +1977,8 @@ class TestMigrate(object):
         'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
         'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
         source_db_tags = 'ceph.osd_id=2,ceph.type=db,ceph.osd_fsid=1234,' \
-        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev'
+        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
+        'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
         source_wal_tags = 'ceph.osd_id=2,ceph.type=wal,ceph.osd_fsid=1234,' \
         'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
         'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
@@ -1381,7 +2032,7 @@ class TestMigrate(object):
         m = migrate.Migrate(argv=[
             '--osd-id', '2',
             '--osd-fsid', '1234',
-            '--from', 'db', 'data',
+            '--from', 'db', 'data', 'wal',
             '--target', 'vgname/db'])
 
         m.main()
@@ -1391,20 +2042,36 @@ class TestMigrate(object):
         for s in self.mock_process_input:
             print(s)
 
+        assert self. mock_process_input[n-4] == [
+            'lvchange',
+            '--deltag', 'ceph.osd_id=2',
+            '--deltag', 'ceph.type=wal',
+            '--deltag', 'ceph.osd_fsid=1234',
+            '--deltag', 'ceph.cluster_name=ceph',
+            '--deltag', 'ceph.db_uuid=dbuuid',
+            '--deltag', 'ceph.db_device=db_dev',
+            '--deltag', 'ceph.wal_uuid=waluuid',
+            '--deltag', 'ceph.wal_device=wal_dev',
+            '/dev/VolGroup/lv3']
+        assert self. mock_process_input[n-3] == [
+            'lvchange',
+            '--deltag', 'ceph.wal_uuid=waluuid',
+            '--deltag', 'ceph.wal_device=wal_dev',
+            '/dev/VolGroup/lv1']
+        assert self. mock_process_input[n-2] == [
+            'lvchange',
+            '--deltag', 'ceph.wal_uuid=waluuid',
+            '--deltag', 'ceph.wal_device=wal_dev',
+            '/dev/VolGroup/lv2']
         assert self. mock_process_input[n-1] == [
             'ceph-bluestore-tool',
             '--path', '/var/lib/ceph/osd/ceph-2',
             '--dev-target', '/var/lib/ceph/osd/ceph-2/block.db',
             '--command', 'bluefs-bdev-migrate',
-            '--devs-source', '/var/lib/ceph/osd/ceph-2/block']
-
-    @patch('os.getuid')
-    def test_migrate_data_wal_to_db(self,
-                                    m_getuid,
-                                    monkeypatch,
-                                    capsys):
-        m_getuid.return_value = 0
+            '--devs-source', '/var/lib/ceph/osd/ceph-2/block',
+            '--devs-source', '/var/lib/ceph/osd/ceph-2/block.wal']
 
+    def test_migrate_data_wal_to_db_active_systemd(self, is_root, monkeypatch, capsys):
         source_tags = 'ceph.osd_id=2,ceph.type=data,ceph.osd_fsid=1234,' \
         'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
         'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
@@ -1456,7 +2123,7 @@ class TestMigrate(object):
             lambda osd_id, osd_fsid: devices)
 
         monkeypatch.setattr("ceph_volume.systemd.systemctl.osd_is_active",
-            lambda id: False)
+            lambda id: True)
 
         monkeypatch.setattr(migrate, 'get_cluster_name',
             lambda osd_id, osd_fsid: 'ceph')
@@ -1467,6 +2134,76 @@ class TestMigrate(object):
             '--from', 'db', 'data', 'wal',
             '--target', 'vgname/db'])
 
+        with pytest.raises(SystemExit) as error:
+            m.main()
+
+        stdout, stderr = capsys.readouterr()
+
+        assert 'Unable to migrate devices associated with OSD ID: 2' == str(error.value)
+        assert '--> OSD is running, stop it with: systemctl stop ceph-osd@2' == stderr.rstrip()
+        assert not stdout
+
+    def test_migrate_data_wal_to_db_no_systemd(self, is_root, monkeypatch):
+        source_tags = 'ceph.osd_id=2,ceph.type=data,ceph.osd_fsid=1234,' \
+        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
+        'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
+        source_db_tags = 'ceph.osd_id=2,ceph.type=db,ceph.osd_fsid=1234,' \
+        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
+        'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
+        source_wal_tags = 'ceph.osd_id=2,ceph.type=wal,ceph.osd_fsid=1234,' \
+        'ceph.cluster_name=ceph,ceph.db_uuid=dbuuid,ceph.db_device=db_dev,' \
+        'ceph.wal_uuid=waluuid,ceph.wal_device=wal_dev'
+
+        data_vol = api.Volume(lv_name='volume1',
+                              lv_uuid='datauuid',
+                              vg_name='vg',
+                              lv_path='/dev/VolGroup/lv1',
+                              lv_tags=source_tags)
+        db_vol = api.Volume(lv_name='volume2',
+                            lv_uuid='dbuuid',
+                            vg_name='vg',
+                            lv_path='/dev/VolGroup/lv2',
+                            lv_tags=source_db_tags)
+
+        wal_vol = api.Volume(lv_name='volume3',
+                             lv_uuid='waluuid',
+                             vg_name='vg',
+                             lv_path='/dev/VolGroup/lv3',
+                             lv_tags=source_wal_tags)
+
+        self.mock_single_volumes = {
+            '/dev/VolGroup/lv1': data_vol,
+            '/dev/VolGroup/lv2': db_vol,
+            '/dev/VolGroup/lv3': wal_vol,
+        }
+        monkeypatch.setattr(migrate.api, 'get_single_lv',
+            self.mock_get_single_lv)
+
+        self.mock_volume = db_vol
+        monkeypatch.setattr(api, 'get_lv_by_fullname',
+            self.mock_get_lv_by_fullname)
+
+        self.mock_process_input = []
+        monkeypatch.setattr(process, 'call', self.mock_process)
+
+        devices = []
+        devices.append([Device('/dev/VolGroup/lv1'), 'block'])
+        devices.append([Device('/dev/VolGroup/lv2'), 'db'])
+        devices.append([Device('/dev/VolGroup/lv3'), 'wal'])
+
+        monkeypatch.setattr(migrate, 'find_associated_devices',
+            lambda osd_id, osd_fsid: devices)
+
+        monkeypatch.setattr(migrate, 'get_cluster_name',
+            lambda osd_id, osd_fsid: 'ceph')
+        monkeypatch.setattr(system, 'chown', lambda path: 0)
+        m = migrate.Migrate(argv=[
+            '--osd-id', '2',
+            '--osd-fsid', '1234',
+            '--from', 'db', 'data', 'wal',
+            '--target', 'vgname/db',
+            '--no-systemd'])
+
         m.main()
 
         n = len(self.mock_process_input)