[stgt] how can I online resize lun with tgtadm?

FUJITA Tomonori fujita.tomonori at lab.ntt.co.jp
Tue Aug 23 19:30:22 CEST 2011


On Mon, 22 Aug 2011 18:08:22 +0200
Jelle de Jong <jelledejong at powercraft.nl> wrote:

> I am using tgt 1:1.0.4-2squeeze1 on Debian stable with back-ports (I
> have been requestion package updates for quite a while now maybe
> somebody here wants to do this?)
> 
> I resized my Logical Volume and my DRBD but mu LUN doesn't grow...
>
> So my question is how can I do an online resize of my LUN?
> 
> See http://paste.debian.net/127011/ for device information.

IIRC, tgtd doesn't support the online resize.

We could implement the feature via tgtadm. But I would prefer that
tgtd could automatically detect the resize. The following patch works
if you use files for logical units. But I'm not sure the patch works
with LVM. Can anyone test the patch with LVM?


diff --git a/usr/bs.c b/usr/bs.c
index d72d090..a9deb1b 100644
--- a/usr/bs.c
+++ b/usr/bs.c
@@ -31,6 +31,7 @@
 #include <sys/types.h>
 #include <sys/epoll.h>
 #include <linux/types.h>
+#include <sys/inotify.h>
 
 #include "list.h"
 #include "tgtd.h"
@@ -303,6 +304,22 @@ destroy_cond_mutex:
 	return 1;
 }
 
+extern void resize_detect(int fd, int events, void *data);
+
+void setup_inotify(void)
+{
+	int ret;
+
+	inotify_fd = inotify_init1(IN_NONBLOCK);
+	if (inotify_fd < 0)
+		eprintf("lun size change detection is disabled\n");
+	else {
+		ret = tgt_event_add(inotify_fd, EPOLLIN,
+				    resize_detect, NULL);
+		eprintf("inotify ready, %d\n", ret);
+	}
+}
+
 int bs_init(void)
 {
 	int ret;
@@ -310,12 +327,14 @@ int bs_init(void)
 	ret = bs_init_signalfd();
 	if (!ret) {
 		eprintf("use signalfd notification\n");
+		setup_inotify();
 		return 0;
 	}
 
 	ret = bs_init_notify_thread();
 	if (!ret) {
 		eprintf("use pthread notification\n");
+		setup_inotify();
 		return 0;
 	}
 
diff --git a/usr/bs_rdwr.c b/usr/bs_rdwr.c
index 29db403..248fb49 100644
--- a/usr/bs_rdwr.c
+++ b/usr/bs_rdwr.c
@@ -31,6 +31,7 @@
 
 #include <linux/fs.h>
 #include <sys/epoll.h>
+#include <sys/inotify.h>
 
 #include "list.h"
 #include "util.h"
@@ -130,6 +131,8 @@ static void bs_rdwr_request(struct scsi_cmd *cmd)
 
 static int bs_rdwr_open(struct scsi_lu *lu, char *path, int *fd, uint64_t *size)
 {
+	int ret;
+
 	*fd = backed_file_open(path, O_RDWR|O_LARGEFILE|lu->bsoflags, size);
 	/* If we get access denied, try opening the file in readonly mode */
 	if (*fd == -1 && (errno == EACCES || errno == EROFS)) {
@@ -140,6 +143,16 @@ static int bs_rdwr_open(struct scsi_lu *lu, char *path, int *fd, uint64_t *size)
 	if (*fd < 0)
 		return *fd;
 
+	if (inotify_fd > 0) {
+		ret = inotify_add_watch(inotify_fd, path, IN_CLOSE_WRITE);
+		if (ret < 0)
+			eprintf("can't check %s\n", path);
+		else {
+			eprintf("checking %s\n", path);
+			lu->notify_fd = ret;
+		}
+	}
+
 	return 0;
 }
 
diff --git a/usr/target.c b/usr/target.c
index ca0d3c8..7d3b4fd 100644
--- a/usr/target.c
+++ b/usr/target.c
@@ -29,6 +29,7 @@
 #include <unistd.h>
 #include <sys/socket.h>
 #include <sys/time.h>
+#include <sys/inotify.h>
 
 #include "list.h"
 #include "util.h"
@@ -63,6 +64,37 @@ static struct device_type_template *device_type_lookup(int type)
 
 static LIST_HEAD(target_list);
 
+void resize_detect(int fd, int events, void *data)
+{
+	struct target *target;
+	struct scsi_lu *lu;
+	struct inotify_event e;
+	int ret;
+
+	ret = read(fd, (char *)&e, sizeof(e));
+
+	eprintf("resize, %d\n", ret);
+	if (ret < 0)
+		return;
+
+	list_for_each_entry(target, &target_list, target_siblings) {
+		list_for_each_entry(lu, &target->device_list, device_siblings) {
+			if (lu->notify_fd == e.wd) {
+				uint64_t size;
+				int fd;
+				eprintf("%s changed\n", lu->path);
+				fd = backed_file_open(lu->path, O_RDONLY, &size);
+				if (fd > 0) {
+					eprintf("new size %lld\n", (long long)size);
+					close(fd);
+					lu->size = size;
+				} else
+					eprintf("failed to open\n");
+			}
+		}
+	}
+}
+
 static struct target *target_lookup(int tid)
 {
 	struct target *target;
diff --git a/usr/tgtd.c b/usr/tgtd.c
index 5e07267..cb51f2c 100644
--- a/usr/tgtd.c
+++ b/usr/tgtd.c
@@ -45,6 +45,7 @@
 unsigned long pagesize, pageshift;
 
 int system_active = 1;
+int inotify_fd = -1;
 static int ep_fd;
 static char program_name[] = "tgtd";
 static LIST_HEAD(tgt_events_list);
diff --git a/usr/tgtd.h b/usr/tgtd.h
index 547edaa..d6cd548 100644
--- a/usr/tgtd.h
+++ b/usr/tgtd.h
@@ -152,6 +152,7 @@ struct scsi_lu {
 	uint64_t size;
 	uint64_t lun;
 	char *path;
+	int notify_fd;
 	int bsoflags;
 	unsigned int blk_shift;
 
@@ -210,6 +211,7 @@ enum mgmt_req_result {
 
 extern int system_active;
 extern int is_debug;
+extern int inotify_fd;
 
 extern int ipc_init(void);
 extern void ipc_exit(void);

--
To unsubscribe from this list: send the line "unsubscribe stgt" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html



More information about the stgt mailing list