}
+typedef struct _checkOwnerData checkOwnerData;
+struct _checkOwnerData {
+ const char **paths;
+ bool chown_fail;
+};
+
+
static int
checkOwner(void *payload,
const void *name,
- void *data)
+ void *opaque)
{
- bool *chown_fail = data;
+ checkOwnerData *data = opaque;
uint32_t owner = *((uint32_t*) payload);
- if (owner % 16 != DEFAULT_UID ||
- owner >> 16 != DEFAULT_GID) {
+ if ((owner % 16 != DEFAULT_UID ||
+ owner >> 16 != DEFAULT_GID) &&
+ !virStringListHasString(data->paths, name)) {
fprintf(stderr,
"Path %s wasn't restored back to its original owner\n",
(const char *) name);
- *chown_fail = true;
+ data->chown_fail = true;
}
return 0;
}
-int checkPaths(void)
+/**
+ * checkPaths:
+ * @paths: a NULL terminated list of paths expected not to be restored
+ *
+ * Check if all paths were restored and if no XATTR was left
+ * behind. Since restore is not done on all domain's paths, some
+ * paths are expected to be not restored. A list of such paths
+ * can be passed in @paths argument. If a path is not restored
+ * but it's on the list no error is indicated.
+ */
+int checkPaths(const char **paths)
{
int ret = -1;
- bool chown_fail = false;
+ checkOwnerData data = { .paths = paths, .chown_fail = false };
bool xattr_fail = false;
+ size_t i;
virMutexLock(&m);
init_hash();
- if ((virHashForEach(chown_paths, checkOwner, &chown_fail)) < 0)
+ for (i = 0; paths && paths[i]; i++) {
+ if (!virHashLookup(chown_paths, paths[i])) {
+ fprintf(stderr, "Unexpected path restored: %s\n", paths[i]);
+ goto cleanup;
+ }
+ }
+
+ if ((virHashForEach(chown_paths, checkOwner, &data)) < 0)
goto cleanup;
if ((virHashForEach(xattr_paths, printXATTR, &xattr_fail)) < 0)
goto cleanup;
- if (chown_fail || xattr_fail)
+ if (data.chown_fail || xattr_fail)
goto cleanup;
ret = 0;