const char *path;
};
-static bool clone_attach_nbd(const char *nbd, const char *path);
static int do_attach_nbd(void *d);
+static bool clone_attach_nbd(const char *nbd, const char *path);
static bool nbd_busy(int idx);
static void nbd_detach(const char *path);
static int nbd_get_partition(const char *src);
p = strchr(orig, ':');
if (p)
*p = '\0';
+
while (1) {
sprintf(path, "/dev/nbd%d", i);
+
if (!file_exists(path))
return false;
+
if (nbd_busy(i)) {
i++;
continue;
}
+
if (!clone_attach_nbd(path, orig))
return false;
+
conf->nbd_idx = i;
return true;
}
}
/* It might take awhile for the partition files to show up */
- if (partition) {
+ if (partition)
if (!wait_for_partition(path))
return -2;
- }
+
ret = mount_unknown_fs(path, bdev->dest, bdev->mntopts);
if (ret < 0)
ERROR("Error mounting %s", bdev->src);
{
if (strncmp(path, "nbd:", 4) == 0)
return true;
+
return false;
}
exit(0);
} else if (fdsi.ssi_signo == SIGCHLD) {
int status;
+
/* If qemu-nbd fails, or is killed by a signal,
* then exit */
while (waitpid(-1, &status, WNOHANG) > 0) {
}
close(sfd);
+
if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)
WARN("Warning: unblocking signals for nbd watcher");
execlp("qemu-nbd", "qemu-nbd", "-c", nbd, path, (char *)NULL);
SYSERROR("Error executing qemu-nbd");
- exit(1);
+ _exit(1);
}
static bool clone_attach_nbd(const char *nbd, const char *path)
pid = lxc_clone(do_attach_nbd, &data, CLONE_NEWPID);
if (pid < 0)
return false;
+
return true;
}
ret = snprintf(path, 100, "/sys/block/nbd%d/pid", idx);
if (ret < 0 || ret >= 100)
return true;
+
return file_exists(path);
}
SYSERROR("Error forking to detach nbd");
return;
}
+
if (pid) {
ret = wait_for_pid(pid);
if (ret < 0)
ERROR("nbd disconnect returned an error");
return;
}
+
execlp("qemu-nbd", "qemu-nbd", "-d", path, (char *)NULL);
SYSERROR("Error executing qemu-nbd");
- exit(1);
+ _exit(1);
}
/*
char *p = strchr(src, ':');
if (!p)
return 0;
+
p = strchr(p+1, ':');
if (!p)
return 0;
+
p++;
+
if (*p < '1' || *p > '9')
return 0;
+
return *p - '0';
}
static bool wait_for_partition(const char *path)
{
int count = 0;
+
while (count < 5) {
if (file_exists(path))
return true;
+
sleep(1);
count++;
}
+
ERROR("Device %s did not show up after 5 seconds", path);
return false;
}