1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-30 17:18:21 +03:00

vgremove: remove online files in run dir

These files are automatically cleared on reboot given
that /run is tmpfs, and that remains the primary way
of clearing online files.

But, if there's extreme use of vgcreate+pvscan+vgremove
between reboots, then removing online files in vgremove
will limit the number of unused online files using space
in /run.
This commit is contained in:
David Teigland 2022-09-14 09:13:58 -05:00
parent a2d33cdfc5
commit 0887896847
5 changed files with 99 additions and 18 deletions

View File

@ -17,6 +17,7 @@
#include "lib/commands/toolcontext.h"
#include "lib/device/device.h"
#include "lib/device/online.h"
#include "lib/metadata/metadata.h"
#include <dirent.h>
@ -504,3 +505,58 @@ do_lookup:
if ((rv < 0) && stat(PVS_LOOKUP_DIR, &st))
log_error_pvscan(cmd, "Failed to create %s %d", PVS_LOOKUP_DIR, errno);
}
void online_lookup_file_remove(const char *vgname)
{
char path[PATH_MAX];
if (dm_snprintf(path, sizeof(path), "%s/%s", PVS_LOOKUP_DIR, vgname) < 0) {
log_error("Path %s/%s is too long.", PVS_LOOKUP_DIR, vgname);
return;
}
log_debug("Unlink pvs_lookup: %s", path);
if (unlink(path) && (errno != ENOENT))
log_sys_debug("unlink", path);
}
static int _online_pvid_file_remove(char *pvid)
{
char path[PATH_MAX];
if (dm_snprintf(path, sizeof(path), "%s/%s", PVS_ONLINE_DIR, pvid) < 0)
return_0;
if (!unlink(path))
return 1;
return 0;
}
/*
* Reboot automatically clearing tmpfs on /run is the main method of removing
* online files. It's important to note that removing the online files for a
* VG is not a technical requirement for anything and could easily be skipped
* if it had any downside. It's only done to clean up the space used in /run
* by the online files, e.g. if there happens to be an extreme amount of
* vgcreate/pvscan/vgremove between reboots that are leaving a large number of
* useless online files consuming tmpfs space.
*/
void online_vgremove(struct volume_group *vg)
{
char pvid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
struct pv_list *pvl;
/*
* online files may not exist for the vg if there has been no
* pvscans or autoactivation.
*/
online_vg_file_remove(vg->name);
online_lookup_file_remove(vg->name);
dm_list_iterate_items(pvl, &vg->pvs) {
memcpy(pvid, &pvl->pv->id.uuid, ID_LEN);
_online_pvid_file_remove(pvid);
}
}

View File

@ -54,5 +54,7 @@ void online_dir_setup(struct cmd_context *cmd);
int get_pvs_online(struct dm_list *pvs_online, const char *vgname);
int get_pvs_lookup(struct dm_list *pvs_online, const char *vgname);
void free_po_list(struct dm_list *list);
void online_lookup_file_remove(const char *vgname);
void online_vgremove(struct volume_group *vg);
#endif

View File

@ -192,6 +192,41 @@ check lv_field $vg2/$lv1 lv_active "active"
vgchange -an $vg1
vgchange -an $vg2
vgremove -f $vg1
vgremove -f $vg2
# vgremove clears online files
PVID1=$(pvs "$bd1" --noheading -o uuid | tr -d - | awk '{print $1}')
PVID2=$(pvs "$bd2" --noheading -o uuid | tr -d - | awk '{print $1}')
PVID3=$(pvs "$bd3" --noheading -o uuid | tr -d - | awk '{print $1}')
_clear_online_files
pvscan --cache --listvg --checkcomplete --vgonline --autoactivation event --udevoutput --journal=output "$bd1"
pvscan --cache --listvg --checkcomplete --vgonline --autoactivation event --udevoutput --journal=output "$bd2"
vgchange -aay --autoactivation event $vg1
check lv_field $vg1/$lv1 lv_active "active"
check lv_field $vg1/$lv2 lv_active "active"
check lv_field $vg2/$lv1 lv_active ""
pvscan --cache --listvg --checkcomplete --vgonline --autoactivation event --udevoutput --journal=output "$bd3"
vgchange -aay --autoactivation event $vg2
check lv_field $vg2/$lv1 lv_active "active"
ls "$RUNDIR/lvm/pvs_online/$PVID1"
ls "$RUNDIR/lvm/pvs_online/$PVID2"
ls "$RUNDIR/lvm/pvs_online/$PVID3"
ls "$RUNDIR/lvm/pvs_lookup/$vg1"
ls "$RUNDIR/lvm/vgs_online/$vg1"
ls "$RUNDIR/lvm/vgs_online/$vg2"
vgremove -y $vg1
not ls "$RUNDIR/lvm/pvs_online/$PVID1"
not ls "$RUNDIR/lvm/pvs_online/$PVID2"
not ls "$RUNDIR/lvm/pvs_lookup/$vg1"
not ls "$RUNDIR/lvm/vgs_online/$vg1"
vgremove -y $vg2
not ls "$RUNDIR/lvm/pvs_online/$PVID3"
not ls "$RUNDIR/lvm/vgs_online/$vg2"

View File

@ -177,21 +177,6 @@ out:
return ret;
}
static void _lookup_file_remove(char *vgname)
{
char path[PATH_MAX];
if (dm_snprintf(path, sizeof(path), "%s/%s", PVS_LOOKUP_DIR, vgname) < 0) {
log_error("Path %s/%s is too long.", PVS_LOOKUP_DIR, vgname);
return;
}
log_debug("Unlink pvs_lookup: %s", path);
if (unlink(path) && (errno != ENOENT))
log_sys_debug("unlink", path);
}
/*
* When a device goes offline we only know its major:minor, not its PVID.
* Since the dev isn't around, we can't read it to get its PVID, so we have to
@ -233,7 +218,7 @@ static void _online_pvid_file_remove_devno(int major, int minor)
if (file_vgname[0]) {
online_vg_file_remove(file_vgname);
_lookup_file_remove(file_vgname);
online_lookup_file_remove(file_vgname);
}
}
}

View File

@ -14,6 +14,7 @@
*/
#include "tools.h"
#include "lib/device/online.h"
static int _vgremove_single(struct cmd_context *cmd, const char *vg_name,
struct volume_group *vg,
@ -75,6 +76,8 @@ static int _vgremove_single(struct cmd_context *cmd, const char *vg_name,
if (!force && !vg_remove_check(vg))
return_ECMD_FAILED;
online_vgremove(vg);
vg_remove_pvs(vg);
if (!vg_remove(vg))